From 9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf Mon Sep 17 00:00:00 2001 From: Apple Date: Sat, 25 Oct 2003 01:25:06 +0000 Subject: [PATCH] Libc-320.tar.gz --- CLIB-LIST | 3 + GNUmakefile | 41 +- Makefile | 13 +- Makefile.fbsd_begin | 24 + Makefile.fbsd_end | 59 + Makefile.inc | 17 +- Makefile.xbs | 126 +- SYSCALL-LIST | 2 + cc-3.3-or-greater | 19 + compat-43/FreeBSD/Makefile.inc | 17 + compat-43/{ => FreeBSD}/creat.2 | 8 +- compat-43/FreeBSD/creat.c | 50 + compat-43/{ => FreeBSD}/gethostid.3 | 10 +- compat-43/{ => FreeBSD}/gethostid.c | 37 +- compat-43/{ => FreeBSD}/getwd.c | 42 +- compat-43/{ => FreeBSD}/killpg.2 | 16 +- compat-43/{ => FreeBSD}/killpg.c | 41 +- compat-43/{ => FreeBSD}/sethostid.c | 35 +- compat-43/{ => FreeBSD}/setpgrp.c | 39 +- .../FreeBSD/setrgid.c | 20 +- compat-43/{ => FreeBSD}/setruid.3 | 2 +- compat-43/{ => FreeBSD}/setruid.c | 34 +- compat-43/Makefile.inc | 17 +- compat-43/sigcompat.c | 3 + db/btree/Makefile.inc | 2 +- db/btree/bt_close.c | 92 +- db/btree/bt_conv.c | 44 +- db/btree/bt_debug.c | 50 +- db/btree/bt_delete.c | 671 ++- db/btree/bt_get.c | 147 +- db/btree/bt_open.c | 99 +- db/btree/bt_overflow.c | 32 +- db/btree/bt_page.c | 29 +- db/btree/bt_put.c | 117 +- db/btree/bt_search.c | 136 +- db/btree/bt_seq.c | 386 +- db/btree/bt_split.c | 80 +- db/btree/bt_utils.c | 119 +- db/btree/btree.h | 275 +- gen/sethostname.c => db/btree/extern.h | 63 +- db/db/db.c | 8 +- db/hash/Makefile.inc | 2 +- db/hash/extern.h | 59 +- db/hash/hash.c | 112 +- db/hash/hash.h | 136 +- db/hash/hash_bigkey.c | 99 +- db/hash/hash_buf.c | 45 +- db/hash/hash_func.c | 46 +- db/hash/hash_log2.c | 18 +- db/hash/hash_page.c | 214 +- db/hash/ndbm.c | 69 +- db/hash/page.h | 21 +- db/mpool/mpool.c | 441 +- db/recno/extern.h | 43 +- db/recno/rec_close.c | 71 +- db/recno/rec_delete.c | 28 +- db/recno/rec_get.c | 111 +- db/recno/rec_open.c | 62 +- db/recno/rec_put.c | 68 +- db/recno/rec_search.c | 15 +- db/recno/rec_seq.c | 26 +- db/recno/rec_utils.c | 82 +- db/recno/recno.h | 9 +- fbsdcompat/_fbsd_compat_.h | 168 + gen/raise.c => fbsdcompat/_fpmath.h | 43 +- compat-43/creat.c => fbsdcompat/fpmath.h | 64 +- stdio/local.h => fbsdcompat/libc_private.h | 125 +- fbsdcompat/machine/atomic.h | 27 + fbsdcompat/namespace.h | 27 + fbsdcompat/spinlock.h | 115 + fbsdcompat/sys/cdefs.h | 495 +++ fbsdcompat/sys/endian.h | 28 + fbsdcompat/un-namespace.h | 27 + gdtoa/FreeBSD/_ldtoa.c | 97 + gdtoa/FreeBSD/gdtoa-dmisc.c | 222 + gdtoa/FreeBSD/gdtoa-dtoa.c | 759 ++++ gdtoa/FreeBSD/gdtoa-gdtoa.c | 764 ++++ gdtoa/FreeBSD/gdtoa-gethex.c | 247 ++ gdtoa/FreeBSD/gdtoa-gmisc.c | 92 + gdtoa/FreeBSD/gdtoa-hd_init.c | 61 + gdtoa/FreeBSD/gdtoa-hexnan.c | 137 + gdtoa/FreeBSD/gdtoa-misc.c | 862 ++++ gdtoa/FreeBSD/gdtoa-smisc.c | 197 + gdtoa/FreeBSD/gdtoa-strtoIg.c | 139 + gdtoa/FreeBSD/gdtoa-strtod.c | 964 +++++ gdtoa/FreeBSD/gdtoa-strtodg.c | 1001 +++++ gdtoa/FreeBSD/gdtoa-strtof.c | 83 + gdtoa/FreeBSD/gdtoa-strtord.c | 99 + gdtoa/FreeBSD/gdtoa-sum.c | 104 + gdtoa/FreeBSD/gdtoa-ulp.c | 76 + gdtoa/FreeBSD/gdtoa.h | 159 + gdtoa/FreeBSD/gdtoa_strtopx.c | 106 + gdtoa/FreeBSD/gdtoaimp.h | 688 ++++ gdtoa/FreeBSD/glue.c | 10 + gdtoa/FreeBSD/machdep_ldisQ.c | 45 + gdtoa/FreeBSD/machdep_ldisd.c | 43 + gdtoa/FreeBSD/machdep_ldisx.c | 45 + gdtoa/Makefile.inc | 15 + gdtoa/arith.h | 39 + gen/{ => FreeBSD}/_rand48.c | 3 + gen/{ => FreeBSD}/alarm.3 | 4 +- gen/{ => FreeBSD}/alarm.c | 31 +- gen/{ => FreeBSD}/basename.3 | 12 +- gen/{ => FreeBSD}/basename.c | 21 +- gen/{ => FreeBSD}/clock.3 | 4 +- gen/{ => FreeBSD}/clock.c | 34 +- gen/{ => FreeBSD}/closedir.c | 55 +- gen/{ => FreeBSD}/ctermid.3 | 12 +- gen/{ => FreeBSD}/ctermid.c | 41 +- gen/{ => FreeBSD}/daemon.3 | 36 +- gen/{ => FreeBSD}/daemon.c | 43 +- gen/{ => FreeBSD}/dirname.3 | 12 +- gen/{ => FreeBSD}/dirname.c | 21 +- gen/{ => FreeBSD}/drand48.c | 3 + gen/{ => FreeBSD}/erand48.c | 3 + gen/{ => FreeBSD}/err.3 | 3 +- gen/{ => FreeBSD}/err.c | 210 +- gen/FreeBSD/errno_.c | 30 + gen/{ => FreeBSD}/exec.3 | 20 +- gen/FreeBSD/exec.c | 266 ++ gen/FreeBSD/exec.c.patch | 12 + gen/{ => FreeBSD}/fmtcheck.3 | 38 +- gen/FreeBSD/fmtcheck.c | 243 ++ gen/{ => FreeBSD}/fnmatch.3 | 6 +- gen/{ => FreeBSD}/fnmatch.c | 4 +- gen/{ => FreeBSD}/ftok.3 | 5 +- gen/{ => FreeBSD}/ftok.c | 9 +- gen/{ => FreeBSD}/getbsize.3 | 2 +- gen/{ => FreeBSD}/getbsize.c | 38 +- gen/{ => FreeBSD}/getcap.3 | 14 +- gen/{ => FreeBSD}/getcap.c | 255 +- gen/{ => FreeBSD}/getcwd.3 | 0 gen/{ => FreeBSD}/getcwd.c | 251 +- gen/FreeBSD/getcwd.c.patch | 32 + gen/{ => FreeBSD}/gethostname.3 | 17 +- gen/{ => FreeBSD}/gethostname.c | 32 +- gen/{ => FreeBSD}/getlogin.c | 100 +- gen/{ => FreeBSD}/getmntinfo.3 | 4 +- gen/{ => FreeBSD}/getmntinfo.c | 29 +- gen/{ => FreeBSD}/getpagesize.3 | 10 +- gen/{ => FreeBSD}/getpagesize.c | 53 +- gen/{ => FreeBSD}/getpass.3 | 5 +- gen/FreeBSD/getprogname.3 | 94 + gen/FreeBSD/getprogname.c | 17 + gen/FreeBSD/getprogname.c.patch | 11 + gen/{ => FreeBSD}/isatty.c | 33 +- gen/FreeBSD/isatty.c.patch | 24 + gen/{ => FreeBSD}/jrand48.c | 3 + gen/{ => FreeBSD}/lcong48.c | 3 + gen/{ => FreeBSD}/lockf.3 | 5 +- gen/{ => FreeBSD}/lockf.c | 17 +- gen/{ => FreeBSD}/lrand48.c | 3 + gen/{ => FreeBSD}/mrand48.c | 3 + gen/{ => FreeBSD}/nice.3 | 0 gen/{ => FreeBSD}/nice.c | 32 +- gen/{ => FreeBSD}/nrand48.c | 3 + gen/{ => FreeBSD}/opendir.c | 139 +- gen/FreeBSD/opendir.c.patch | 19 + gen/{ => FreeBSD}/pause.3 | 0 gen/{ => FreeBSD}/pause.c | 34 +- gen/{ => FreeBSD}/popen.3 | 4 +- gen/{ => FreeBSD}/popen.c | 118 +- gen/FreeBSD/popen.c.patch | 12 + gen/FreeBSD/pselect.3 | 127 + gen/FreeBSD/pselect.3.patch | 11 + gen/FreeBSD/pselect.c | 78 + gen/FreeBSD/pselect.c.patch | 13 + gen/{ => FreeBSD}/psignal.3 | 4 +- gen/FreeBSD/psignal.c | 67 + gen/{ => FreeBSD}/raise.3 | 0 gen/FreeBSD/raise.c | 48 + gen/{ => FreeBSD}/rand48.3 | 18 +- gen/{ => FreeBSD}/rand48.h | 4 +- gen/{ => FreeBSD}/readdir.c | 96 +- gen/FreeBSD/readpassphrase.3 | 191 + gen/FreeBSD/readpassphrase.c | 178 + gen/{ => FreeBSD}/rewinddir.c | 33 +- gen/{ => FreeBSD}/scandir.3 | 8 +- gen/{ => FreeBSD}/scandir.c | 82 +- gen/{ => FreeBSD}/seed48.c | 3 + gen/{ => FreeBSD}/seekdir.c | 40 +- gen/FreeBSD/sethostname.c | 53 + gen/{ => FreeBSD}/setmode.3 | 2 +- gen/{ => FreeBSD}/setmode.c | 67 +- gen/FreeBSD/setprogname.c | 19 + gen/FreeBSD/setprogname.c.patch | 21 + gen/{ => FreeBSD}/siginterrupt.3 | 4 +- gen/{ => FreeBSD}/siginterrupt.c | 37 +- gen/{ => FreeBSD}/siglist.c | 32 +- gen/FreeBSD/siglist.c.patch | 7 + gen/{ => FreeBSD}/signal.3 | 18 +- gen/FreeBSD/signal.c | 65 + gen/FreeBSD/signal.c.patch | 53 + gen/{ => FreeBSD}/sleep.3 | 0 gen/FreeBSD/sleep.c | 72 + gen/{ => FreeBSD}/srand48.c | 0 gen/{ => FreeBSD}/stringlist.3 | 55 +- gen/FreeBSD/stringlist.c | 125 + gen/{ => FreeBSD}/sysctl.3 | 37 +- gen/{ => FreeBSD}/sysctl.c | 47 +- gen/{ => FreeBSD}/sysctlbyname.c | 6 +- gen/FreeBSD/sysctlnametomib.c | 55 + gen/{ => FreeBSD}/telldir.c | 106 +- compat-43/setrgid.c => gen/FreeBSD/telldir.h | 75 +- gen/{ => FreeBSD}/termios.c | 94 +- gen/{ => FreeBSD}/time.3 | 0 gen/FreeBSD/time.3.patch | 17 + gen/{ => FreeBSD}/time.c | 29 +- gen/{ => FreeBSD}/times.3 | 0 gen/{ => FreeBSD}/times.c | 33 +- gen/{ => FreeBSD}/timezone.3 | 12 +- gen/{ => FreeBSD}/timezone.c | 72 +- gen/{ => FreeBSD}/ttyname.3 | 4 +- gen/{ => FreeBSD}/ttyname.c | 180 +- gen/{ => FreeBSD}/ttyslot.c | 43 +- gen/{ => FreeBSD}/ualarm.3 | 0 gen/{ => FreeBSD}/ualarm.c | 35 +- gen/FreeBSD/ulimit.3 | 98 + gen/FreeBSD/ulimit.c | 68 + gen/{ => FreeBSD}/unvis.3 | 26 +- gen/{ => FreeBSD}/unvis.c | 126 +- gen/{ => FreeBSD}/usleep.3 | 2 +- gen/{ => FreeBSD}/usleep.c | 10 +- gen/{ => FreeBSD}/utime.3 | 3 +- gen/{ => FreeBSD}/utime.c | 31 +- gen/{ => FreeBSD}/vis.3 | 14 +- gen/{ => FreeBSD}/vis.c | 81 +- gen/{ => FreeBSD}/wait.c | 40 +- gen/{ => FreeBSD}/wait3.c | 34 +- gen/FreeBSD/waitpid.c | 54 + gen/Makefile.inc | 107 +- gen/OSSystemInfo.c | 65 + gen/arc4random.c | 24 + gen/{strchr.c => cache.c} | 33 +- gen/crypt.c | 25 +- gen/ctime.c | 1402 ------- gen/devname.c | 1 + gen/disklabel.c | 8 +- gen/errlst.c | 9 +- gen/exec.c | 326 -- gen/fstab.c | 228 -- gen/fts.c | 18 +- gen/getdomainname.3 | 6 +- gen/getgrent.3 | 7 +- gen/getgrouplist.c | 113 - gen/getpass.c | 112 - gen/getpeereid.3 | 4 +- gen/getpwent.3 | 48 +- gen/getusershell.3 | 1 - gen/getusershell.c | 2 +- gen/getvfsbyname.c | 4 +- gen/getvfsent.3 | 183 - gen/glob.c | 867 ---- gen/hton.c | 53 - gen/intro.3 | 167 + gen/malloc.3 | 253 ++ gen/malloc.c | 357 +- gen/msgctl.3 | 206 - gen/msgget.3 | 139 - gen/msgrcv.3 | 202 - gen/msgsnd.3 | 167 - gen/nlist.c | 8 +- gen/psignal.c | 88 - gen/pwcache.3 | 7 +- gen/pwcache.c | 161 - gen/rcmd.c | 432 -- gen/readdir_r.c | 51 - gen/scalable_malloc.c | 3617 ++++++++++++----- gen/scalable_malloc.h | 13 +- gen/setlogin.c | 2 + gen/signal.c | 109 - gen/sigsetops.c | 7 +- gen/stack_logging.c | 5 +- gen/strtofflags.c | 24 + gen/sysconf.3 | 3 + gen/sysconf.c | 5 +- gen/syslog.3 | 2 +- gen/syslog.c | 2 +- gen/ulimit.c | 32 - gen/waitpid.c | 75 - i386/gen/Makefile.inc | 14 +- i386/gen/bcopy.s | 110 +- i386/gen/bcopy_init.c | 9 - i386/gen/bzero.s | 86 +- i386/gen/icacheinval.s | 31 + i386/gen/insque.c | 58 - i386/gen/remque.c | 58 - i386/mach/mach_absolute_time.c | 38 +- i386/pthreads/Makefile.inc | 6 + i386/pthreads/get_cpu_capabilities.s | 37 + .../pthreads/init_cpu_capabilities.c | 29 +- i386/pthreads/pthread_getspecific.s | 34 + .../pthreads/pthread_self.s | 16 +- i386/pthreads/pthread_set_self.s | 36 + i386/stdlib/gdtoa.mk | 2 + i386/string/Makefile.inc | 11 + {string => i386/string}/strcmp.s | 15 - i386/sys/Makefile.inc | 29 +- i386/sys/{sem_unlink.s => aio_cancel.s} | 5 +- i386/sys/{sem_open.s => aio_error.s} | 5 +- i386/sys/aio_fsync.s | 28 + i386/sys/aio_read.s | 28 + i386/sys/aio_return.s | 28 + i386/sys/aio_suspend.s | 28 + i386/sys/aio_write.s | 28 + i386/sys/audit.s | 28 + i386/sys/auditctl.s | 28 + i386/sys/auditon.s | 28 + i386/sys/auditsvc.s | 28 + i386/sys/fhopen.s | 28 + i386/sys/fork.s | 3 +- i386/sys/{shm_open.s => fsctl.s} | 4 +- i386/sys/getaudit.s | 28 + i386/sys/getaudit_addr.s | 28 + i386/sys/getauid.s | 28 + i386/sys/getpid.s | 42 +- i386/sys/kevent.s | 28 + i386/sys/kqueue.s | 28 + i386/sys/kqueue_from_portset_np.s | 28 + i386/sys/kqueue_portset_np.s | 28 + i386/sys/lio_listio.s | 28 + i386/sys/msync.s | 2 +- i386/sys/nfsclnt.s | 28 + i386/sys/setaudit.s | 28 + i386/sys/setaudit_addr.s | 28 + i386/sys/setauid.s | 28 + i386/sys/vfork.s | 187 +- i386/threads/Makefile.inc | 2 - include/Makefile.inc | 139 +- include/NSSystemDirectories.h | 9 + string/rindix.c => include/aio.h | 25 +- string/strchr.c => include/alloca.h | 44 +- include/arpa/tftp.h | 6 +- include/authentication.h | 4 + include/crt_externs.h | 4 + include/ctype.h | 165 +- include/db.h | 37 +- include/dirent.h | 29 +- include/err.h | 23 +- include/fnmatch.h | 2 +- include/fstab.h | 10 +- include/fts.h | 12 +- include/getopt.h | 72 + include/glob.h | 16 +- include/grp.h | 21 +- include/iso646.h | 44 + include/kvm.h | 24 +- include/langinfo.h | 121 + include/libc.h | 9 +- include/libgen.h | 8 +- include/locale.h | 11 +- include/malloc/Makefile.inc | 2 + include/malloc/malloc.h | 184 + include/monetary.h | 39 + include/monitor.h | 4 + include/mpool.h | 138 +- include/ndbm.h | 20 +- include/netdb.h | 262 -- include/nl_types.h | 51 + include/nlist.h | 2 +- include/objc/malloc.h | 131 +- include/objc/zone.h | 10 +- include/pwd.h | 17 +- include/readpassphrase.h | 47 + include/regex.h | 10 +- include/regexp.h | 8 +- include/rune.h | 16 +- include/runetype.h | 34 +- include/search.h | 61 + include/signal.h | 45 +- include/standards.h | 8 +- include/stddef.h | 22 +- include/stdio.h | 198 +- include/stdlib.h | 225 +- include/strhash.h | 68 + include/string.h | 81 +- include/stringlist.h | 57 + include/time.h | 42 +- gen/difftime.c => include/timeconv.h | 56 +- include/ttyent.h | 8 +- include/ulimit.h | 4 + include/unistd.h | 313 +- include/util.h | 49 +- include/utime.h | 2 +- include/vis.h | 12 +- include/wchar.h | 216 + include/wctype.h | 138 + internat/Makefile.inc | 2 +- internat/NXIsAscii.c | 1 + internat/NXToLower.c | 1 + internat/NXToUpper.c | 1 + internat/_NXToLower.c | 1 + internat/_NXToUpper.c | 1 + locale/{ => FreeBSD}/big5.c | 8 +- locale/FreeBSD/big5.c.patch | 32 + locale/FreeBSD/btowc.3 | 79 + locale/FreeBSD/btowc.c | 45 + locale/FreeBSD/collate.c | 291 ++ locale/FreeBSD/collate.c.patch | 10 + locale/{ => FreeBSD}/collate.h | 28 +- locale/{ => FreeBSD}/collcmp.c | 5 +- locale/{ => FreeBSD}/ctype.3 | 9 +- .../FreeBSD/digittoint.3 | 68 +- locale/{ => FreeBSD}/euc.4 | 2 +- locale/{ => FreeBSD}/euc.c | 49 +- locale/FreeBSD/euc.c.patch | 37 + locale/FreeBSD/fix_grouping.c | 83 + locale/{ => FreeBSD}/frune.c | 5 + locale/{ => FreeBSD}/isalnum.3 | 16 +- locale/{ => FreeBSD}/isalpha.3 | 16 +- locale/{ => FreeBSD}/isascii.3 | 10 +- locale/{ => FreeBSD}/isblank.3 | 31 +- locale/{ => FreeBSD}/iscntrl.3 | 30 +- locale/{ => FreeBSD}/isctype.c | 46 +- locale/{ => FreeBSD}/isdigit.3 | 35 +- locale/{ => FreeBSD}/isgraph.3 | 21 +- locale/{ => FreeBSD}/islower.3 | 16 +- locale/{ => FreeBSD}/isprint.3 | 19 +- locale/{ => FreeBSD}/ispunct.3 | 20 +- locale/{ => FreeBSD}/isspace.3 | 34 +- locale/{ => FreeBSD}/isupper.3 | 16 +- locale/FreeBSD/iswalnum.3 | 162 + locale/FreeBSD/iswctype.c | 214 + locale/{ => FreeBSD}/isxdigit.3 | 44 +- locale/FreeBSD/ldpart.c | 161 + locale/FreeBSD/ldpart.c.patch | 35 + locale/FreeBSD/ldpart.h | 39 + locale/FreeBSD/ldpart.h.patch | 11 + locale/FreeBSD/lmessages.c | 91 + locale/FreeBSD/lmessages.c.patch | 11 + locale/FreeBSD/lmessages.h | 42 + locale/FreeBSD/lmonetary.c | 179 + locale/FreeBSD/lmonetary.c.patch | 11 + locale/FreeBSD/lmonetary.h | 59 + locale/FreeBSD/lnumeric.c | 92 + locale/FreeBSD/lnumeric.c.patch | 11 + locale/FreeBSD/lnumeric.h | 41 + locale/FreeBSD/localeconv.c | 111 + locale/FreeBSD/localeconv.c.patch | 83 + locale/FreeBSD/mblen.c | 58 + locale/FreeBSD/mbrlen.3 | 145 + locale/FreeBSD/mbrlen.c | 37 + locale/FreeBSD/mbrtowc.3 | 140 + locale/FreeBSD/mbrtowc.c | 75 + locale/{ => FreeBSD}/mbrune.3 | 26 +- locale/{ => FreeBSD}/mbrune.c | 5 + locale/FreeBSD/mbsinit.3 | 64 + locale/FreeBSD/mbsinit.c | 42 + locale/FreeBSD/mbsrtowcs.3 | 110 + locale/FreeBSD/mbsrtowcs.c | 74 + locale/FreeBSD/mbstowcs.c | 88 + locale/FreeBSD/mbtowc.c | 61 + locale/{ => FreeBSD}/mskanji.c | 61 +- locale/FreeBSD/mskanji.c.patch | 42 + locale/{ => FreeBSD}/multibyte.3 | 27 +- locale/{ => FreeBSD}/nl_langinfo.3 | 6 +- locale/FreeBSD/nl_langinfo.c | 201 + locale/FreeBSD/nl_langinfo.c.patch | 11 + locale/{ => FreeBSD}/nomacros.c | 3 + locale/{ => FreeBSD}/none.c | 17 +- locale/{ => FreeBSD}/rune.3 | 52 +- locale/{ => FreeBSD}/rune.c | 53 +- locale/FreeBSD/rune.c.patch | 10 + locale/{ => FreeBSD}/runetype.c | 7 +- locale/FreeBSD/runetype.c.patch | 53 + locale/{ => FreeBSD}/setinvalidrune.c | 4 + locale/{ => FreeBSD}/setlocale.3 | 75 +- locale/{ => FreeBSD}/setlocale.c | 237 +- locale/FreeBSD/setlocale.c.patch | 11 + locale/{ => FreeBSD}/setlocale.h | 11 +- locale/{ => FreeBSD}/setrunelocale.c | 106 +- locale/{ => FreeBSD}/table.c | 10 +- locale/{ => FreeBSD}/toascii.3 | 3 +- locale/{ => FreeBSD}/tolower.3 | 32 +- locale/{ => FreeBSD}/tolower.c | 9 +- locale/FreeBSD/tolower.c.patch | 37 + locale/{ => FreeBSD}/toupper.3 | 32 +- locale/{ => FreeBSD}/toupper.c | 9 +- locale/FreeBSD/toupper.c.patch | 37 + gen/modf.3 => locale/FreeBSD/towlower.3 | 51 +- gen/ldexp.3 => locale/FreeBSD/towupper.3 | 56 +- locale/{ => FreeBSD}/utf2.4 | 12 +- locale/{ => FreeBSD}/utf2.c | 8 +- locale/FreeBSD/utf8.5 | 131 + locale/FreeBSD/utf8.c | 204 + locale/FreeBSD/utf8.c.patch | 64 + locale/FreeBSD/wcrtomb.3 | 105 + locale/FreeBSD/wcrtomb.c | 52 + locale/FreeBSD/wcsftime.3 | 66 + locale/FreeBSD/wcsftime.c | 105 + locale/FreeBSD/wcsrtombs.3 | 110 + locale/FreeBSD/wcsrtombs.c | 90 + locale/FreeBSD/wcstod.3 | 70 + locale/FreeBSD/wcstod.c | 107 + locale/FreeBSD/wcstof.c | 84 + locale/FreeBSD/wcstoimax.c | 128 + locale/FreeBSD/wcstol.3 | 94 + locale/FreeBSD/wcstol.c | 121 + locale/FreeBSD/wcstold.c | 84 + locale/FreeBSD/wcstoll.c | 127 + locale/FreeBSD/wcstombs.c | 91 + locale/FreeBSD/wcstoul.c | 119 + locale/{ansi.c => FreeBSD/wcstoull.c} | 189 +- locale/FreeBSD/wcstoumax.c | 126 + locale/FreeBSD/wctob.c | 41 + locale/FreeBSD/wctomb.c | 66 + locale/FreeBSD/wctrans.3 | 122 + locale/FreeBSD/wctrans.c | 84 + locale/FreeBSD/wctype.3 | 117 + locale/FreeBSD/wctype.c | 73 + locale/FreeBSD/wcwidth.3 | 86 + locale/FreeBSD/wcwidth.c | 65 + locale/Makefile.inc | 60 +- locale/collate.c | 212 - locale/lconv.c | 33 + mach/Makefile.inc | 57 +- mach/clock.defs | 24 + mach/clock_priv.defs | 24 + mach/error_codes.c | 24 + mach/errorlib.h | 24 + mach/exc_catcher.c | 1 + mach/exc_catcher_state.c | 1 + mach/exc_catcher_state_identity.c | 1 + mach/externs.h | 24 + mach/fprintf_stderr.c | 24 + mach/headers/Makefile.inc | 2 + mach/headers/errorlib.h | 28 + mach/headers/mach.h | 5 + mach/headers/mach_error.h | 4 + mach/headers/mach_init.h | 5 +- mach/headers/mach_interface.h | 24 + mach/headers/port_obj.h | 28 + i386/sys/shm_unlink.s => mach/headers/task.h | 16 +- mach/headers/thread_act.h | 31 + mach/host_priv.defs | 24 + mach/host_security.defs | 24 + mach/ledger.defs | 24 + mach/lock_set.defs | 24 + mach/mach_error.c | 2 + mach/mach_error_string.c | 24 + mach/mach_init.c | 9 - mach/mach_init_ports.c | 25 + mach/mach_msg.c | 21 +- mach/ms_thread_switch.c | 26 + mach/notify.defs | 24 + mach/panic.c | 24 + mach/port_obj.c | 24 + mach/processor.defs | 24 + mach/processor_set.defs | 24 + mach/sbrk.c | 7 +- mach/servers/Makefile.inc | 29 - mach/servers/netname.defs | 24 + mach/slot_name.c | 4 +- mach/task.defs | 24 + mach/thread_act.defs | 24 + mach/vm_map.defs | 24 + net/{ => FreeBSD}/addr2ascii.3 | 12 +- net/FreeBSD/addr2ascii.c | 95 + net/FreeBSD/ascii2addr.c | 75 + net/{ => FreeBSD}/inet.3 | 13 +- net/{ => FreeBSD}/inet_addr.c | 88 +- net/{ => FreeBSD}/inet_lnaof.c | 40 +- net/{ => FreeBSD}/inet_makeaddr.c | 40 +- net/{ => FreeBSD}/inet_net.3 | 6 +- net/FreeBSD/inet_net_ntop.c | 148 + net/FreeBSD/inet_net_pton.c | 214 + net/FreeBSD/inet_neta.c | 92 + net/{ => FreeBSD}/inet_netof.c | 40 +- net/{ => FreeBSD}/inet_network.c | 62 +- net/{ => FreeBSD}/inet_ntoa.c | 57 +- net/{ => FreeBSD}/linkaddr.3 | 6 +- net/{ => FreeBSD}/linkaddr.c | 49 +- net/FreeBSD/nsap_addr.c | 113 + net/FreeBSD/nsap_addr.c.patch | 26 + net/{ => FreeBSD}/recv.c | 37 +- {compat-43 => net/FreeBSD}/send.c | 34 +- net/Makefile.inc | 33 +- net/getaddrinfo.3 | 619 --- net/gethostbyname.3 | 380 -- net/getifaddrs.3 | 164 - net/getipnodebyname.3 | 461 --- net/getnameinfo.3 | 311 -- net/getnetent.3 | 172 - net/getprotoent.3 | 149 - net/getservent.3 | 158 - net/if_indextoname.3 | 142 - net/inet6_option_space.3 | 445 -- net/inet6_rthdr_space.3 | 323 -- net/ns.3 | 133 - net/nsap_addr.c | 125 - net/nsdispatch.3 | 231 -- net/rcmd.3 | 298 -- nls/FreeBSD/catclose.3 | 64 + nls/FreeBSD/catgets.3 | 69 + nls/FreeBSD/catopen.3 | 157 + nls/FreeBSD/msgcat.c | 503 +++ nls/FreeBSD/msgcat.c.patch | 11 + nls/FreeBSD/msgcat.h | 155 + nls/Makefile.inc | 16 +- ppc/gen/Makefile.inc | 17 +- ppc/gen/bcopy.s | 1149 +----- ppc/gen/bzero.s | 105 +- ppc/gen/icacheinval.s | 37 + ppc/gen/insque.c | 58 - ppc/gen/remque.c | 58 - ppc/gen/setjmperr.c | 3 + ppc/gen/strcat.c | 47 - ppc/gen/strcmp.c | 56 - ppc/gen/strcpy.c | 55 - ppc/gen/strncat.c | 55 - ppc/gen/strncmp.c | 59 - ppc/gen/strncpy.c | 64 - ppc/mach/mach_absolute_time.s | 17 +- ppc/pthreads/Makefile.inc | 6 + ppc/pthreads/get_cpu_capabilities.s | 37 + ppc/pthreads/init_cpu_capabilities.c | 44 + ppc/pthreads/pthread_getspecific.s | 36 + ppc/pthreads/pthread_self.s | 33 + .../cthread.s => pthreads/pthread_set_self.s} | 6 +- ppc/stdlib/gdtoa.mk | 2 + ppc/string/Makefile.inc | 18 + ppc/string/memcmp.s | 164 + ppc/string/strcat.s | 168 + ppc/string/strcmp.s | 166 + ppc/string/strcpy.s | 118 + ppc/string/strlcat.s | 274 ++ ppc/string/strlcpy.s | 183 + ppc/{gen => string}/strlen.s | 5 +- ppc/string/strncat.s | 217 + ppc/string/strncmp.s | 188 + ppc/string/strncpy.s | 221 + ppc/sys/ATPgetreq.s | 1 - ppc/sys/ATPgetrsp.s | 1 - ppc/sys/ATPsndreq.s | 1 - ppc/sys/ATPsndrsp.s | 1 - ppc/sys/ATgetmsg.s | 1 - ppc/sys/ATputmsg.s | 1 - ppc/sys/ATsocket.s | 1 - ppc/sys/Makefile.inc | 31 +- ppc/sys/SYS.h | 2 +- ppc/sys/_pthread_kill.s | 1 - ppc/sys/_sysctl.s | 1 - ppc/sys/accept.s | 1 - ppc/sys/access.s | 1 - ppc/sys/acct.s | 1 - ppc/sys/add_profil.s | 1 - ppc/sys/adjtime.s | 1 - ppc/sys/{shm_open.s => aio_cancel.s} | 3 +- ppc/sys/{sem_open.s => aio_error.s} | 3 +- ppc/sys/{shm_unlink.s => aio_fsync.s} | 3 +- ppc/sys/{sem_unlink.s => aio_read.s} | 3 +- ppc/sys/aio_return.s | 28 + ppc/sys/aio_suspend.s | 28 + ppc/sys/aio_write.s | 28 + ppc/sys/audit.s | 28 + ppc/sys/auditctl.s | 28 + ppc/sys/auditon.s | 28 + ppc/sys/auditsvc.s | 28 + ppc/sys/bind.s | 1 - ppc/sys/chdir.s | 1 - ppc/sys/checkuseraccess.s | 1 - ppc/sys/chflags.s | 1 - ppc/sys/chmod.s | 1 - ppc/sys/chown.s | 1 - ppc/sys/chroot.s | 1 - ppc/sys/close.s | 1 - ppc/sys/connect.s | 1 - ppc/sys/dup.s | 1 - ppc/sys/dup2.s | 1 - ppc/sys/exchangedata.s | 1 - ppc/sys/execve.s | 1 - ppc/sys/fchdir.s | 1 - ppc/sys/fchflags.s | 1 - ppc/sys/fchmod.s | 1 - ppc/sys/fchown.s | 1 - ppc/sys/fcntl.s | 1 - ppc/sys/fhopen.s | 28 + ppc/sys/flock.s | 1 - ppc/sys/fork.s | 1 - ppc/sys/fpathconf.s | 1 - ppc/sys/fsctl.s | 28 + ppc/sys/fstat.s | 1 - ppc/sys/fstatfs.s | 1 - ppc/sys/fstatv.s | 1 - ppc/sys/fsync.s | 1 - ppc/sys/ftruncate.s | 1 - ppc/sys/futimes.s | 1 - ppc/sys/getattrlist.s | 1 - ppc/sys/getaudit.s | 28 + ppc/sys/getaudit_addr.s | 28 + ppc/sys/getauid.s | 28 + ppc/sys/getdirentries.s | 1 - ppc/sys/getdirentriesattr.s | 1 - ppc/sys/getfh.s | 1 - ppc/sys/getfsstat.s | 1 - ppc/sys/getgid.s | 1 - ppc/sys/getgroups.s | 1 - ppc/sys/getitimer.s | 1 - ppc/sys/getpeername.s | 1 - ppc/sys/getpgid.s | 1 - ppc/sys/getpgrp.s | 1 - ppc/sys/getpriority.s | 1 - ppc/sys/getrlimit.s | 1 - ppc/sys/getrusage.s | 1 - ppc/sys/getsid.s | 1 - ppc/sys/getsockname.s | 1 - ppc/sys/getsockopt.s | 1 - ppc/sys/getuid.s | 1 - ppc/sys/ioctl.s | 1 - ppc/sys/issetugid.s | 1 - ppc/sys/kevent.s | 28 + ppc/sys/kill.s | 1 - ppc/sys/kqueue.s | 28 + ppc/sys/kqueue_from_portset_np.s | 29 + ppc/sys/kqueue_portset_np.s | 28 + ppc/sys/ktrace.s | 1 - ppc/sys/link.s | 1 - ppc/sys/lio_listio.s | 28 + ppc/sys/listen.s | 1 - ppc/sys/load_shared_file.s | 1 - ppc/sys/lseek.s | 1 - ppc/sys/lstat.s | 1 - ppc/sys/lstatv.s | 1 - ppc/sys/madvise.s | 1 - ppc/sys/mincore.s | 1 - ppc/sys/minherit.s | 1 - ppc/sys/mkcomplex.s | 1 - ppc/sys/mkdir.s | 1 - ppc/sys/mkfifo.s | 1 - ppc/sys/mknod.s | 1 - ppc/sys/mlock.s | 1 - ppc/sys/mlockall.s | 1 - ppc/sys/mmap.s | 1 - ppc/sys/mount.s | 1 - ppc/sys/mprotect.s | 1 - ppc/sys/msgctl.s | 1 - ppc/sys/msgget.s | 1 - ppc/sys/msgrcv.s | 1 - ppc/sys/msgsnd.s | 1 - ppc/sys/msgsys.s | 1 - ppc/sys/msync.s | 3 +- ppc/sys/munlock.s | 1 - ppc/sys/munlockall.s | 1 - ppc/sys/munmap.s | 1 - ppc/sys/new_system_shared_regions.s | 1 - ppc/sys/nfsclnt.s | 28 + ppc/sys/nfssvc.s | 1 - ppc/sys/open.s | 1 - ppc/sys/pathconf.s | 1 - ppc/sys/ppc_gettimeofday.s | 9 +- ppc/sys/pread.s | 1 - ppc/sys/profil.s | 1 - ppc/sys/pthread_sigmask.s | 1 - ppc/sys/pwrite.s | 1 - ppc/sys/quota.s | 1 - ppc/sys/quotactl.s | 1 - ppc/sys/read.s | 1 - ppc/sys/readlink.s | 1 - ppc/sys/readv.s | 1 - ppc/sys/recvfrom.s | 1 - ppc/sys/recvmsg.s | 1 - ppc/sys/rename.s | 1 - ppc/sys/reset_shared_file.s | 1 - ppc/sys/revoke.s | 1 - ppc/sys/rmdir.s | 1 - ppc/sys/searchfs.s | 1 - ppc/sys/select.s | 1 - ppc/sys/sem_close.s | 1 - ppc/sys/sem_destroy.s | 1 - ppc/sys/sem_getvalue.s | 1 - ppc/sys/sem_init.s | 1 - ppc/sys/sem_post.s | 1 - ppc/sys/sem_trywait.s | 1 - ppc/sys/sem_wait.s | 1 - ppc/sys/semconfig.s | 1 - ppc/sys/semctl.s | 1 - ppc/sys/semget.s | 1 - ppc/sys/semop.s | 1 - ppc/sys/semsys.s | 1 - ppc/sys/sendmsg.s | 1 - ppc/sys/sendto.s | 1 - ppc/sys/setattrlist.s | 1 - ppc/sys/setaudit.s | 28 + ppc/sys/setaudit_addr.s | 28 + ppc/sys/setauid.s | 28 + ppc/sys/setegid.s | 1 - ppc/sys/seteuid.s | 1 - ppc/sys/setgid.s | 1 - ppc/sys/setgroups.s | 1 - ppc/sys/setitimer.s | 1 - ppc/sys/setjmp.s | 7 +- ppc/sys/setpgid.s | 1 - ppc/sys/setpriority.s | 1 - ppc/sys/setprivexec.s | 1 - ppc/sys/setquota.s | 1 - ppc/sys/setrlimit.s | 1 - ppc/sys/setsid.s | 1 - ppc/sys/setsockopt.s | 1 - ppc/sys/settimeofday.s | 1 - ppc/sys/setuid.s | 1 - ppc/sys/shmat.s | 1 - ppc/sys/shmctl.s | 1 - ppc/sys/shmdt.s | 1 - ppc/sys/shmget.s | 1 - ppc/sys/shmsys.s | 1 - ppc/sys/shutdown.s | 1 - ppc/sys/sigaltstack.s | 1 - ppc/sys/sigpending.s | 1 - ppc/sys/sigprocmask.s | 1 - ppc/sys/sigwait.s | 1 - ppc/sys/socket.s | 1 - ppc/sys/socketpair.s | 1 - ppc/sys/stat.s | 1 - ppc/sys/statfs.s | 1 - ppc/sys/statv.s | 1 - ppc/sys/swapon.s | 1 - ppc/sys/symlink.s | 1 - ppc/sys/sync.s | 1 - ppc/sys/systable.s | 1 - ppc/sys/truncate.s | 1 - ppc/sys/umask.s | 1 - ppc/sys/undelete.s | 1 - ppc/sys/unlink.s | 1 - ppc/sys/unmount.s | 1 - ppc/sys/utimes.s | 1 - ppc/sys/wait4.s | 1 - ppc/sys/write.s | 1 - ppc/sys/writev.s | 1 - pthreads/Makefile.inc | 8 +- pthreads/lock.s | 99 +- pthreads/mk_pthread_impl.c | 24 + pthreads/posix_sched.h | 24 + pthreads/pthread.c | 249 +- pthreads/pthread.h | 291 +- pthreads/pthread_cond.c | 461 ++- pthreads/pthread_impl.h | 25 + pthreads/pthread_internals.h | 126 +- pthreads/pthread_join.3 | 2 - pthreads/pthread_machdep.h | 32 +- pthreads/pthread_mutex.c | 516 ++- pthreads/pthread_mutexattr.3 | 94 +- pthreads/pthread_rwlock.c | 24 + pthreads/pthread_spinlock.h | 105 + pthreads/pthread_tsd.c | 76 +- pthreads/sched.h | 29 + pthreads/stack.s | 24 + pthreads/thread_setup.c | 24 + regex/FreeBSD/COPYRIGHT | 56 + regex/FreeBSD/WHATSNEW | 94 + regex/FreeBSD/cclass.h | 63 + regex/FreeBSD/cname.h | 142 + regex/{ => FreeBSD}/engine.c | 258 +- regex/{ => FreeBSD}/re_format.7 | 4 +- regex/{ => FreeBSD}/regcomp.c | 1020 +++-- regex/{ => FreeBSD}/regerror.c | 86 +- regex/{ => FreeBSD}/regex.3 | 66 +- regex/{ => FreeBSD}/regex2.h | 85 +- regex/{ => FreeBSD}/regexec.c | 69 +- regex/FreeBSD/regexec.c.patch | 11 + regex/{ => FreeBSD}/regfree.c | 38 +- regex/{ => FreeBSD}/utils.h | 30 +- regex/Makefile.inc | 11 +- regex/cclass.h | 91 - regex/cname.h | 162 - stdio/FreeBSD/_flock_stub.c | 149 + stdio/{ => FreeBSD}/asprintf.c | 42 +- stdio/{ => FreeBSD}/clrerr.c | 36 +- stdio/{ => FreeBSD}/fclose.3 | 4 +- stdio/{ => FreeBSD}/fclose.c | 44 +- stdio/{ => FreeBSD}/fdopen.c | 41 +- stdio/FreeBSD/feof.c | 63 + stdio/{ => FreeBSD}/ferror.3 | 39 +- stdio/FreeBSD/ferror.c | 63 + stdio/{ => FreeBSD}/fflush.3 | 8 +- stdio/{ => FreeBSD}/fflush.c | 95 +- stdio/FreeBSD/fgetc.c | 59 + stdio/{ => FreeBSD}/fgetln.3 | 0 stdio/{ => FreeBSD}/fgetln.c | 65 +- stdio/FreeBSD/fgetpos.c | 55 + stdio/{ => FreeBSD}/fgets.3 | 48 +- stdio/{ => FreeBSD}/fgets.c | 55 +- stdio/FreeBSD/fgetwc.c | 109 + stdio/FreeBSD/fgetws.3 | 125 + stdio/FreeBSD/fgetws.c | 75 + stdio/FreeBSD/fileno.c | 64 + stdio/{ => FreeBSD}/findfp.c | 172 +- stdio/FreeBSD/findfp.c.patch | 60 + stdio/{ => FreeBSD}/flags.c | 39 +- stdio/FreeBSD/floatio.h | 56 + stdio/FreeBSD/flockfile.3 | 104 + stdio/{ => FreeBSD}/fopen.3 | 53 +- stdio/{ => FreeBSD}/fopen.c | 47 +- stdio/FreeBSD/fprintf.c | 56 + stdio/FreeBSD/fpurge.c | 74 + stdio/{ => FreeBSD}/fputc.c | 44 +- stdio/{ => FreeBSD}/fputs.3 | 7 +- stdio/FreeBSD/fputs.3.patch | 16 + stdio/{ => FreeBSD}/fputs.c | 46 +- stdio/FreeBSD/fputs.c.patch | 22 + stdio/FreeBSD/fputwc.c | 87 + string/strcat.3 => stdio/FreeBSD/fputws.3 | 95 +- stdio/FreeBSD/fputws.c | 53 + stdio/{ => FreeBSD}/fread.3 | 6 +- stdio/{ => FreeBSD}/fread.c | 49 +- stdio/{ => FreeBSD}/freopen.c | 114 +- stdio/FreeBSD/fscanf.c | 62 + stdio/{ => FreeBSD}/fseek.3 | 26 +- stdio/{ => FreeBSD}/fseek.c | 201 +- stdio/{ => FreeBSD}/fsetpos.c | 32 +- stdio/{ => FreeBSD}/ftell.c | 127 +- stdio/{ => FreeBSD}/funopen.3 | 0 stdio/{ => FreeBSD}/funopen.c | 38 +- stdio/{ => FreeBSD}/fvwrite.c | 30 +- stdio/{ => FreeBSD}/fvwrite.h | 5 +- stdlib/rand.c => stdio/FreeBSD/fwalk.c | 94 +- stdio/FreeBSD/fwide.3 | 97 + stdio/FreeBSD/fwide.c | 51 + stdio/FreeBSD/fwprintf.c | 45 + stdio/{ => FreeBSD}/fwrite.c | 47 +- stdio/FreeBSD/fwscanf.c | 45 + stdio/{ => FreeBSD}/getc.3 | 46 +- stdio/FreeBSD/getc.c | 58 + stdio/{ => FreeBSD}/getchar.c | 42 +- stdio/FreeBSD/gets.c | 81 + stdio/{ => FreeBSD}/getw.c | 31 +- stdio/FreeBSD/getwc.3 | 118 + stdio/FreeBSD/getwc.c | 46 + stdio/FreeBSD/getwchar.c | 45 + stdio/{ => FreeBSD}/glue.h | 33 +- stdio/FreeBSD/glue.h.patch | 9 + stdio/FreeBSD/local.h | 148 + stdio/FreeBSD/local.h.patch | 11 + stdio/{ => FreeBSD}/makebuf.c | 45 +- stdio/{ => FreeBSD}/mktemp.3 | 6 +- stdio/{ => FreeBSD}/mktemp.c | 58 +- stdio/{ => FreeBSD}/perror.c | 48 +- stdio/FreeBSD/printf.3 | 880 ++++ stdio/FreeBSD/printf.3.patch | 52 + stdio/FreeBSD/printf.c | 56 + stdio/{ => FreeBSD}/putc.3 | 59 +- stdio/{fgetc.c => FreeBSD/putc.c} | 53 +- stdio/{ => FreeBSD}/putchar.c | 54 +- stdio/{ => FreeBSD}/puts.c | 40 +- stdio/FreeBSD/puts.c.patch | 30 + stdio/{ => FreeBSD}/putw.c | 40 +- gen/frexp.3 => stdio/FreeBSD/putwc.3 | 105 +- stdio/FreeBSD/putwc.c | 46 + stdio/FreeBSD/putwchar.c | 45 + stdio/{ => FreeBSD}/refill.c | 70 +- stdio/{ => FreeBSD}/remove.3 | 0 stdio/{ => FreeBSD}/remove.c | 6 +- stdio/FreeBSD/rewind.c | 65 + stdio/{ => FreeBSD}/rget.c | 35 +- stdio/{ => FreeBSD}/scanf.3 | 317 +- stdio/FreeBSD/scanf.c | 62 + stdio/{ => FreeBSD}/setbuf.3 | 17 +- stdio/{ => FreeBSD}/setbuf.c | 35 +- stdio/{ => FreeBSD}/setbuffer.c | 35 +- stdio/{ => FreeBSD}/setvbuf.c | 47 +- stdio/FreeBSD/snprintf.c | 75 + stdio/FreeBSD/sprintf.c | 67 + stdio/{ => FreeBSD}/sscanf.c | 54 +- stdio/FreeBSD/sscanf.c.patch | 20 + stdio/{ => FreeBSD}/stdio.3 | 70 +- stdio/{ => FreeBSD}/stdio.c | 171 +- stdio/FreeBSD/swprintf.c | 45 + stdio/FreeBSD/swscanf.c | 45 + stdio/{ => FreeBSD}/tempnam.c | 47 +- stdio/{ => FreeBSD}/tmpfile.c | 58 +- stdio/{ => FreeBSD}/tmpnam.3 | 83 +- stdio/{ => FreeBSD}/tmpnam.c | 47 +- stdio/{ => FreeBSD}/ungetc.3 | 5 +- stdio/{ => FreeBSD}/ungetc.c | 73 +- stdio/FreeBSD/ungetwc.3 | 99 + stdio/FreeBSD/ungetwc.c | 77 + stdio/FreeBSD/unlocked.c | 94 + stdio/{ => FreeBSD}/vasprintf.c | 24 +- stdio/{ => FreeBSD}/vfprintf.c | 1485 ++++--- stdio/FreeBSD/vfprintf.c.patch | 718 ++++ stdio/{ => FreeBSD}/vfscanf.c | 717 +++- stdio/FreeBSD/vfwprintf.c | 1607 ++++++++ stdio/FreeBSD/vfwprintf.c.patch | 732 ++++ stdio/FreeBSD/vfwscanf.c | 873 ++++ stdio/{ => FreeBSD}/vprintf.c | 36 +- stdio/{ => FreeBSD}/vscanf.c | 45 +- stdio/FreeBSD/vsnprintf.c | 79 + stdio/{ => FreeBSD}/vsprintf.c | 43 +- stdio/{ => FreeBSD}/vsscanf.c | 45 +- stdio/FreeBSD/vswprintf.c | 94 + stdio/FreeBSD/vswscanf.c | 98 + stdio/FreeBSD/vwprintf.c | 39 + stdio/FreeBSD/vwscanf.c | 39 + stdio/{ => FreeBSD}/wbuf.c | 45 +- stdio/{printf.3 => FreeBSD/wprintf.3} | 571 ++- stdio/FreeBSD/wprintf.3.patch | 52 + stdio/FreeBSD/wprintf.c | 45 + stdio/FreeBSD/wscanf.3 | 483 +++ stdio/FreeBSD/wscanf.c | 45 + stdio/{ => FreeBSD}/wsetup.c | 33 +- stdio/Makefile.inc | 60 +- stdio/feof.c | 74 - stdio/ferror.c | 74 - stdio/fgetpos.c | 74 - stdio/fileno.c | 74 - stdio/floatio.h | 68 - stdio/fprintf.c | 90 - stdio/fpurge.c | 86 - stdio/fscanf.c | 90 - stdio/fwalk.c | 81 - stdio/getc.c | 74 - stdio/gets.c | 89 - stdio/hexfloat.c | 192 + stdio/printf.c | 89 - stdio/putc.c | 75 - stdio/rewind.c | 72 - stdio/scanf.c | 89 - stdio/snprintf.c | 98 - stdio/sprintf.c | 97 - stdio/vsnprintf.c | 82 - stdlib/FreeBSD/_Exit_.c | 22 + stdlib/{ => FreeBSD}/abort.3 | 0 stdlib/FreeBSD/abort.c | 86 + stdlib/FreeBSD/abort.c.patch | 18 + stdlib/{ => FreeBSD}/abs.3 | 10 +- {i386/gen => stdlib/FreeBSD}/abs.c | 33 +- stdlib/{ => FreeBSD}/alloca.3 | 0 stdlib/FreeBSD/alloca.3.patch | 12 + stdlib/{ => FreeBSD}/atexit.3 | 20 +- stdlib/{ => FreeBSD}/atexit.c | 64 +- stdlib/{ => FreeBSD}/atexit.h | 32 +- stdlib/{ => FreeBSD}/atof.3 | 12 +- stdlib/{ => FreeBSD}/atof.c | 34 +- stdlib/{ => FreeBSD}/atoi.3 | 12 +- stdlib/{ => FreeBSD}/atoi.c | 33 +- stdlib/{ => FreeBSD}/atol.3 | 51 +- stdlib/{ => FreeBSD}/atol.c | 32 +- stdlib/FreeBSD/atoll.c | 44 + stdlib/{ => FreeBSD}/bsearch.3 | 0 stdlib/{ => FreeBSD}/bsearch.c | 43 +- stdlib/{ => FreeBSD}/div.3 | 16 +- stdlib/{ => FreeBSD}/div.c | 29 +- stdlib/{ => FreeBSD}/exit.3 | 78 +- stdlib/{ => FreeBSD}/exit.c | 53 +- stdlib/FreeBSD/exit.c.patch | 30 + stdlib/{ => FreeBSD}/getenv.3 | 29 +- stdlib/{ => FreeBSD}/getenv.c | 82 +- stdlib/FreeBSD/getenv.c.patch | 19 + stdlib/{ => FreeBSD}/getopt.3 | 4 +- stdlib/{ => FreeBSD}/getopt.c | 50 +- stdlib/FreeBSD/getopt_long.3 | 400 ++ stdlib/FreeBSD/getopt_long.c | 494 +++ stdlib/{ => FreeBSD}/getsubopt.3 | 0 stdlib/{ => FreeBSD}/getsubopt.c | 45 +- stdlib/FreeBSD/grantpt.3 | 224 + stdlib/FreeBSD/grantpt.c | 259 ++ stdlib/{ => FreeBSD}/hcreate.3 | 32 +- stdlib/FreeBSD/hcreate.c | 185 + stdlib/{ => FreeBSD}/heapsort.c | 40 +- stdlib/FreeBSD/imaxabs.3 | 62 + stdlib/FreeBSD/imaxabs.c | 36 + stdlib/FreeBSD/imaxdiv.3 | 73 + stdlib/FreeBSD/imaxdiv.c | 45 + stdlib/FreeBSD/insque.3 | 61 + stdlib/FreeBSD/insque.c | 47 + stdlib/{ => FreeBSD}/labs.3 | 8 +- stdlib/{ => FreeBSD}/labs.c | 28 +- stdlib/{ => FreeBSD}/ldiv.3 | 18 +- stdlib/{ => FreeBSD}/ldiv.c | 29 +- stdlib/FreeBSD/llabs.3 | 62 + stdlib/FreeBSD/llabs.c | 36 + stdlib/FreeBSD/lldiv.3 | 73 + stdlib/FreeBSD/lldiv.c | 45 + stdlib/FreeBSD/lsearch.3 | 105 + stdlib/FreeBSD/lsearch.c | 64 + stdlib/{ => FreeBSD}/memory.3 | 0 stdlib/{ => FreeBSD}/merge.c | 58 +- stdlib/{ => FreeBSD}/putenv.c | 31 +- stdlib/{ => FreeBSD}/qsort.3 | 89 +- stdlib/{ => FreeBSD}/qsort.c | 118 +- stdlib/FreeBSD/qsort_r.c | 8 + stdlib/FreeBSD/qsort_r.c.patch | 8 + stdlib/{ => FreeBSD}/radixsort.3 | 0 stdlib/{ => FreeBSD}/radixsort.c | 79 +- stdlib/{ => FreeBSD}/rand.3 | 4 +- stdlib/FreeBSD/rand.c | 172 + stdlib/{ => FreeBSD}/random.3 | 0 stdlib/{ => FreeBSD}/random.c | 185 +- stdlib/{ => FreeBSD}/reallocf.c | 6 +- stdlib/{ => FreeBSD}/realpath.3 | 12 +- stdlib/FreeBSD/realpath.c | 197 + stdlib/FreeBSD/remque.c | 30 + stdlib/{ => FreeBSD}/setenv.c | 76 +- stdlib/FreeBSD/setenv.c.patch | 68 + stdlib/{ => FreeBSD}/strfmon.3 | 87 +- stdlib/FreeBSD/strfmon.3.patch | 11 + stdlib/FreeBSD/strfmon.c | 603 +++ stdlib/FreeBSD/strhash.c | 407 ++ stdlib/{ => FreeBSD}/strtod.3 | 114 +- stdlib/FreeBSD/strtoimax.c | 141 + stdlib/{ => FreeBSD}/strtol.3 | 92 +- stdlib/{ => FreeBSD}/strtol.c | 87 +- stdlib/{ => FreeBSD}/strtoll.c | 57 +- stdlib/{ => FreeBSD}/strtoq.c | 15 +- stdlib/{ => FreeBSD}/strtoul.3 | 77 +- stdlib/{ => FreeBSD}/strtoul.c | 81 +- stdlib/{ => FreeBSD}/strtoull.c | 56 +- stdlib/FreeBSD/strtoumax.c | 119 + stdlib/{ => FreeBSD}/strtouq.c | 15 +- stdlib/{ => FreeBSD}/system.3 | 4 +- stdlib/{ => FreeBSD}/system.c | 92 +- stdlib/FreeBSD/tdelete.c | 71 + stdlib/FreeBSD/tfind.c | 48 + stdlib/{ => FreeBSD}/tsearch.3 | 30 +- stdlib/FreeBSD/tsearch.c | 58 + stdlib/FreeBSD/twalk.c | 58 + stdlib/Makefile.inc | 57 +- stdlib/a64l.c | 24 + stdlib/abort.c | 109 - stdlib/l64a.c | 24 + stdlib/malloc.3 | 483 --- stdlib/strtod.c | 2518 ------------ stdtime/{ => FreeBSD}/asctime.c | 22 +- stdtime/{ => FreeBSD}/ctime.3 | 22 +- stdtime/{ => FreeBSD}/difftime.c | 8 +- stdtime/{ => FreeBSD}/localtime.c | 462 +-- stdtime/FreeBSD/localtime.c.patch | 463 +++ stdtime/{ => FreeBSD}/private.h | 17 +- stdtime/{ => FreeBSD}/strftime.3 | 43 +- stdtime/{ => FreeBSD}/strftime.c | 66 +- stdtime/{ => FreeBSD}/strptime.3 | 39 +- stdtime/{ => FreeBSD}/strptime.c | 139 +- stdtime/{ => FreeBSD}/time2posix.3 | 2 +- stdtime/FreeBSD/time2posix.3.patch | 14 + stdtime/FreeBSD/time32.c | 100 + stdtime/FreeBSD/timelocal.c | 117 + stdtime/FreeBSD/timelocal.c.patch | 11 + stdtime/{ => FreeBSD}/timelocal.h | 41 +- stdtime/{ => FreeBSD}/tzfile.5 | 2 +- stdtime/{ => FreeBSD}/tzfile.h | 4 +- stdtime/Makefile.inc | 18 +- stdtime/timelocal.c | 244 -- string/{ => FreeBSD}/bcmp.3 | 11 +- {i386/gen => string/FreeBSD}/bcmp.c | 44 +- string/{ => FreeBSD}/bcopy.3 | 11 +- string/FreeBSD/bcopy.c | 139 + string/{ => FreeBSD}/bstring.3 | 0 string/{ => FreeBSD}/bzero.3 | 11 +- string/FreeBSD/bzero.c | 5 + string/FreeBSD/bzero.c.patch | 8 + string/{ => FreeBSD}/ffs.3 | 11 +- {i386/gen => string/FreeBSD}/ffs.c | 41 +- string/{ => FreeBSD}/index.3 | 13 +- string/{ => FreeBSD}/index.c | 51 +- string/{ => FreeBSD}/memccpy.3 | 0 string/{ => FreeBSD}/memccpy.c | 40 +- string/{ => FreeBSD}/memchr.3 | 0 string/{ => FreeBSD}/memchr.c | 35 +- string/{ => FreeBSD}/memcmp.3 | 0 string/{ => FreeBSD}/memcmp.c | 38 +- string/{ => FreeBSD}/memcpy.3 | 11 +- string/FreeBSD/memcpy.3.patch | 39 + string/FreeBSD/memcpy.c | 5 + string/FreeBSD/memcpy.c.patch | 8 + string/{ => FreeBSD}/memmove.3 | 0 string/FreeBSD/memmove.c | 5 + string/FreeBSD/memmove.c.patch | 8 + string/{ => FreeBSD}/memset.3 | 0 string/{ => FreeBSD}/memset.c | 57 +- string/{ => FreeBSD}/rindex.3 | 13 +- string/{ => FreeBSD}/rindex.c | 51 +- string/FreeBSD/stpcpy.c | 46 + string/{ => FreeBSD}/strcasecmp.3 | 11 +- string/FreeBSD/strcasecmp.c | 77 + string/FreeBSD/strcasestr.c | 65 + string/FreeBSD/strcat.3 | 164 + {i386/gen => string/FreeBSD}/strcat.c | 38 +- string/{ => FreeBSD}/strchr.3 | 6 +- string/FreeBSD/strchr.c | 5 + string/FreeBSD/strchr.c.patch | 8 + string/{ => FreeBSD}/strcmp.3 | 0 {i386/gen => string/FreeBSD}/strcmp.c | 39 +- string/{ => FreeBSD}/strcoll.3 | 5 +- string/FreeBSD/strcoll.c | 86 + string/{ => FreeBSD}/strcpy.3 | 74 +- {i386/gen => string/FreeBSD}/strcpy.c | 39 +- string/{ => FreeBSD}/strcspn.3 | 0 string/{ => FreeBSD}/strcspn.c | 38 +- string/{ => FreeBSD}/strdup.3 | 0 string/{ => FreeBSD}/strdup.c | 35 +- string/{ => FreeBSD}/strerror.3 | 79 +- string/FreeBSD/strerror.c | 99 + string/{ => FreeBSD}/string.3 | 7 +- string/{ => FreeBSD}/strlcat.c | 23 +- string/{ => FreeBSD}/strlcpy.3 | 3 +- string/{ => FreeBSD}/strlcpy.c | 16 +- string/{ => FreeBSD}/strlen.3 | 0 {i386/gen => string/FreeBSD}/strlen.c | 37 +- string/{ => FreeBSD}/strmode.3 | 0 string/{ => FreeBSD}/strmode.c | 35 +- {i386/gen => string/FreeBSD}/strncat.c | 44 +- {i386/gen => string/FreeBSD}/strncmp.c | 40 +- {i386/gen => string/FreeBSD}/strncpy.c | 44 +- string/FreeBSD/strnstr.c | 72 + string/{ => FreeBSD}/strpbrk.3 | 0 string/{ => FreeBSD}/strpbrk.c | 36 +- string/{ => FreeBSD}/strrchr.3 | 0 string/FreeBSD/strrchr.c | 5 + string/FreeBSD/strrchr.c.patch | 8 + string/{ => FreeBSD}/strsep.3 | 13 +- string/{ => FreeBSD}/strsep.c | 47 +- string/FreeBSD/strsignal.c | 74 + string/FreeBSD/strsignal.c.patch | 11 + string/{ => FreeBSD}/strspn.3 | 0 string/{ => FreeBSD}/strspn.c | 36 +- string/{ => FreeBSD}/strstr.3 | 13 +- string/{ => FreeBSD}/strstr.c | 38 +- string/{ => FreeBSD}/strtok.3 | 7 +- string/{ => FreeBSD}/strtok.c | 172 +- string/{ => FreeBSD}/strxfrm.3 | 7 +- string/FreeBSD/strxfrm.c | 83 + string/{ => FreeBSD}/swab.3 | 4 +- string/{ => FreeBSD}/swab.c | 47 +- string/FreeBSD/wcscat.c | 53 + string/FreeBSD/wcschr.c | 41 + string/FreeBSD/wcscmp.c | 61 + string/FreeBSD/wcscoll.3 | 112 + string/FreeBSD/wcscoll.c | 97 + string/FreeBSD/wcscpy.c | 51 + string/FreeBSD/wcscspn.c | 60 + string/FreeBSD/wcslcat.c | 77 + string/FreeBSD/wcslcpy.c | 73 + string/FreeBSD/wcslen.c | 50 + string/FreeBSD/wcsncat.c | 60 + string/FreeBSD/wcsncmp.c | 63 + string/FreeBSD/wcsncpy.c | 68 + string/FreeBSD/wcspbrk.c | 60 + string/FreeBSD/wcsrchr.c | 47 + string/FreeBSD/wcsspn.c | 62 + string/FreeBSD/wcsstr.c | 67 + string/FreeBSD/wcstok.3 | 133 + string/FreeBSD/wcstok.c | 90 + .../FreeBSD/wcswidth.3 | 71 +- string/FreeBSD/wcswidth.c | 61 + string/FreeBSD/wcsxfrm.3 | 126 + string/FreeBSD/wcsxfrm.c | 115 + string/{ => FreeBSD}/wmemchr.3 | 14 +- string/FreeBSD/wmemchr.c | 55 + string/FreeBSD/wmemcmp.c | 56 + string/FreeBSD/wmemcpy.c | 48 + string/FreeBSD/wmemmove.c | 48 + string/FreeBSD/wmemset.c | 54 + string/Makefile.inc | 31 +- string/strcasecmp.c | 139 - string/strcoll.c | 74 - string/strerror.c | 89 - string/strftime.c | 313 -- string/strxfrm.c | 88 - sys/Makefile.inc | 7 +- sys/SYSCALL-LIST | 2 + sys/crt_externs.c | 27 +- sys/errno.c | 2 +- sys/fix-3375657.c | 413 ++ sys/getdtablesize.c | 24 + sys/gettimeofday.c | 48 +- sys/sem_open.c | 70 + gen/sleep.c => sys/sem_unlink.c | 50 +- sys/shm_open.c | 59 + i386/threads/thread.c => sys/shm_unlink.c | 58 +- sys/sigaction.c | 3 +- sys/sigtramp.c | 159 +- sys/sigwait.2 | 9 +- threads/cprocs.c | 9 +- threads/cthreads.c | 17 +- threads/lu_utils.c | 28 + threads/mig_support.c | 16 +- util/Makefile.inc | 7 +- util/fparseln.3 | 156 + util/fparseln.c | 257 ++ util/opendev.3 | 104 + util/opendev.c | 109 + util/pty.c | 2 + 1281 files changed, 60700 insertions(+), 32576 deletions(-) create mode 100644 Makefile.fbsd_begin create mode 100644 Makefile.fbsd_end create mode 100755 cc-3.3-or-greater create mode 100644 compat-43/FreeBSD/Makefile.inc rename compat-43/{ => FreeBSD}/creat.2 (94%) create mode 100644 compat-43/FreeBSD/creat.c rename compat-43/{ => FreeBSD}/gethostid.3 (95%) rename compat-43/{ => FreeBSD}/gethostid.c (64%) rename compat-43/{ => FreeBSD}/getwd.c (62%) rename compat-43/{ => FreeBSD}/killpg.2 (94%) rename compat-43/{ => FreeBSD}/killpg.c (62%) rename compat-43/{ => FreeBSD}/sethostid.c (64%) rename compat-43/{ => FreeBSD}/setpgrp.c (62%) rename locale/localeconv.c => compat-43/FreeBSD/setrgid.c (84%) rename compat-43/{ => FreeBSD}/setruid.3 (96%) rename compat-43/{ => FreeBSD}/setruid.c (63%) rename gen/sethostname.c => db/btree/extern.h (66%) create mode 100644 fbsdcompat/_fbsd_compat_.h rename gen/raise.c => fbsdcompat/_fpmath.h (71%) rename compat-43/creat.c => fbsdcompat/fpmath.h (66%) rename stdio/local.h => fbsdcompat/libc_private.h (52%) create mode 100644 fbsdcompat/machine/atomic.h create mode 100644 fbsdcompat/namespace.h create mode 100644 fbsdcompat/spinlock.h create mode 100644 fbsdcompat/sys/cdefs.h create mode 100644 fbsdcompat/sys/endian.h create mode 100644 fbsdcompat/un-namespace.h create mode 100644 gdtoa/FreeBSD/_ldtoa.c create mode 100644 gdtoa/FreeBSD/gdtoa-dmisc.c create mode 100644 gdtoa/FreeBSD/gdtoa-dtoa.c create mode 100644 gdtoa/FreeBSD/gdtoa-gdtoa.c create mode 100644 gdtoa/FreeBSD/gdtoa-gethex.c create mode 100644 gdtoa/FreeBSD/gdtoa-gmisc.c create mode 100644 gdtoa/FreeBSD/gdtoa-hd_init.c create mode 100644 gdtoa/FreeBSD/gdtoa-hexnan.c create mode 100644 gdtoa/FreeBSD/gdtoa-misc.c create mode 100644 gdtoa/FreeBSD/gdtoa-smisc.c create mode 100644 gdtoa/FreeBSD/gdtoa-strtoIg.c create mode 100644 gdtoa/FreeBSD/gdtoa-strtod.c create mode 100644 gdtoa/FreeBSD/gdtoa-strtodg.c create mode 100644 gdtoa/FreeBSD/gdtoa-strtof.c create mode 100644 gdtoa/FreeBSD/gdtoa-strtord.c create mode 100644 gdtoa/FreeBSD/gdtoa-sum.c create mode 100644 gdtoa/FreeBSD/gdtoa-ulp.c create mode 100644 gdtoa/FreeBSD/gdtoa.h create mode 100644 gdtoa/FreeBSD/gdtoa_strtopx.c create mode 100644 gdtoa/FreeBSD/gdtoaimp.h create mode 100644 gdtoa/FreeBSD/glue.c create mode 100644 gdtoa/FreeBSD/machdep_ldisQ.c create mode 100644 gdtoa/FreeBSD/machdep_ldisd.c create mode 100644 gdtoa/FreeBSD/machdep_ldisx.c create mode 100644 gdtoa/Makefile.inc create mode 100644 gdtoa/arith.h rename gen/{ => FreeBSD}/_rand48.c (92%) rename gen/{ => FreeBSD}/alarm.3 (97%) rename gen/{ => FreeBSD}/alarm.c (67%) rename gen/{ => FreeBSD}/basename.3 (95%) rename gen/{ => FreeBSD}/basename.c (88%) rename gen/{ => FreeBSD}/clock.3 (96%) rename gen/{ => FreeBSD}/clock.c (64%) rename gen/{ => FreeBSD}/closedir.c (60%) rename gen/{ => FreeBSD}/ctermid.3 (96%) rename gen/{ => FreeBSD}/ctermid.c (65%) rename gen/{ => FreeBSD}/daemon.3 (71%) rename gen/{ => FreeBSD}/daemon.c (63%) rename gen/{ => FreeBSD}/dirname.3 (94%) rename gen/{ => FreeBSD}/dirname.c (89%) rename gen/{ => FreeBSD}/drand48.c (83%) rename gen/{ => FreeBSD}/erand48.c (85%) rename gen/{ => FreeBSD}/err.3 (98%) rename gen/{ => FreeBSD}/err.c (51%) create mode 100644 gen/FreeBSD/errno_.c rename gen/{ => FreeBSD}/exec.3 (95%) create mode 100644 gen/FreeBSD/exec.c create mode 100644 gen/FreeBSD/exec.c.patch rename gen/{ => FreeBSD}/fmtcheck.3 (89%) create mode 100644 gen/FreeBSD/fmtcheck.c rename gen/{ => FreeBSD}/fnmatch.3 (97%) rename gen/{ => FreeBSD}/fnmatch.c (97%) rename gen/{ => FreeBSD}/ftok.3 (94%) rename gen/{ => FreeBSD}/ftok.c (86%) rename gen/{ => FreeBSD}/getbsize.3 (97%) rename gen/{ => FreeBSD}/getbsize.c (71%) rename gen/{ => FreeBSD}/getcap.3 (98%) rename gen/{ => FreeBSD}/getcap.c (85%) rename gen/{ => FreeBSD}/getcwd.3 (100%) rename gen/{ => FreeBSD}/getcwd.c (51%) create mode 100644 gen/FreeBSD/getcwd.c.patch rename gen/{ => FreeBSD}/gethostname.3 (94%) rename gen/{ => FreeBSD}/gethostname.c (66%) rename gen/{ => FreeBSD}/getlogin.c (58%) rename gen/{ => FreeBSD}/getmntinfo.3 (96%) rename gen/{ => FreeBSD}/getmntinfo.c (71%) rename gen/{ => FreeBSD}/getpagesize.3 (93%) rename gen/{ => FreeBSD}/getpagesize.c (62%) rename gen/{ => FreeBSD}/getpass.3 (96%) create mode 100644 gen/FreeBSD/getprogname.3 create mode 100644 gen/FreeBSD/getprogname.c create mode 100644 gen/FreeBSD/getprogname.c.patch rename gen/{ => FreeBSD}/isatty.c (63%) create mode 100644 gen/FreeBSD/isatty.c.patch rename gen/{ => FreeBSD}/jrand48.c (83%) rename gen/{ => FreeBSD}/lcong48.c (87%) rename gen/{ => FreeBSD}/lockf.3 (98%) rename gen/{ => FreeBSD}/lockf.c (89%) rename gen/{ => FreeBSD}/lrand48.c (84%) rename gen/{ => FreeBSD}/mrand48.c (84%) rename gen/{ => FreeBSD}/nice.3 (100%) rename gen/{ => FreeBSD}/nice.c (67%) rename gen/{ => FreeBSD}/nrand48.c (83%) rename gen/{ => FreeBSD}/opendir.c (70%) create mode 100644 gen/FreeBSD/opendir.c.patch rename gen/{ => FreeBSD}/pause.3 (100%) rename gen/{ => FreeBSD}/pause.c (64%) rename gen/{ => FreeBSD}/popen.3 (98%) rename gen/{ => FreeBSD}/popen.c (67%) create mode 100644 gen/FreeBSD/popen.c.patch create mode 100644 gen/FreeBSD/pselect.3 create mode 100644 gen/FreeBSD/pselect.3.patch create mode 100644 gen/FreeBSD/pselect.c create mode 100644 gen/FreeBSD/pselect.c.patch rename gen/{ => FreeBSD}/psignal.3 (96%) create mode 100644 gen/FreeBSD/psignal.c rename gen/{ => FreeBSD}/raise.3 (100%) create mode 100644 gen/FreeBSD/raise.c rename gen/{ => FreeBSD}/rand48.3 (94%) rename gen/{ => FreeBSD}/rand48.h (86%) rename gen/{ => FreeBSD}/readdir.c (63%) create mode 100644 gen/FreeBSD/readpassphrase.3 create mode 100644 gen/FreeBSD/readpassphrase.c rename gen/{ => FreeBSD}/rewinddir.c (65%) rename gen/{ => FreeBSD}/scandir.3 (93%) rename gen/{ => FreeBSD}/scandir.c (69%) rename gen/{ => FreeBSD}/seed48.c (89%) rename gen/{ => FreeBSD}/seekdir.c (66%) create mode 100644 gen/FreeBSD/sethostname.c rename gen/{ => FreeBSD}/setmode.3 (97%) rename gen/{ => FreeBSD}/setmode.c (91%) create mode 100644 gen/FreeBSD/setprogname.c create mode 100644 gen/FreeBSD/setprogname.c.patch rename gen/{ => FreeBSD}/siginterrupt.3 (97%) rename gen/{ => FreeBSD}/siginterrupt.c (65%) rename gen/{ => FreeBSD}/siglist.c (78%) create mode 100644 gen/FreeBSD/siglist.c.patch rename gen/{ => FreeBSD}/signal.3 (96%) create mode 100644 gen/FreeBSD/signal.c create mode 100644 gen/FreeBSD/signal.c.patch rename gen/{ => FreeBSD}/sleep.3 (100%) create mode 100644 gen/FreeBSD/sleep.c rename gen/{ => FreeBSD}/srand48.c (100%) rename gen/{ => FreeBSD}/stringlist.3 (83%) create mode 100644 gen/FreeBSD/stringlist.c rename gen/{ => FreeBSD}/sysctl.3 (97%) rename gen/{ => FreeBSD}/sysctl.c (78%) rename gen/{ => FreeBSD}/sysctlbyname.c (89%) create mode 100644 gen/FreeBSD/sysctlnametomib.c rename gen/{ => FreeBSD}/telldir.c (56%) rename compat-43/setrgid.c => gen/FreeBSD/telldir.h (51%) rename gen/{ => FreeBSD}/termios.c (67%) rename gen/{ => FreeBSD}/time.3 (100%) create mode 100644 gen/FreeBSD/time.3.patch rename gen/{ => FreeBSD}/time.c (65%) rename gen/{ => FreeBSD}/times.3 (100%) rename gen/{ => FreeBSD}/times.c (70%) rename gen/{ => FreeBSD}/timezone.3 (95%) rename gen/{ => FreeBSD}/timezone.c (64%) rename gen/{ => FreeBSD}/ttyname.3 (97%) rename gen/{ => FreeBSD}/ttyname.c (50%) rename gen/{ => FreeBSD}/ttyslot.c (62%) rename gen/{ => FreeBSD}/ualarm.3 (100%) rename gen/{ => FreeBSD}/ualarm.c (69%) create mode 100644 gen/FreeBSD/ulimit.3 create mode 100644 gen/FreeBSD/ulimit.c rename gen/{ => FreeBSD}/unvis.3 (96%) rename gen/{ => FreeBSD}/unvis.c (75%) rename gen/{ => FreeBSD}/usleep.3 (97%) rename gen/{ => FreeBSD}/usleep.c (91%) rename gen/{ => FreeBSD}/utime.3 (96%) rename gen/{ => FreeBSD}/utime.c (67%) rename gen/{ => FreeBSD}/vis.3 (96%) rename gen/{ => FreeBSD}/vis.c (74%) rename gen/{ => FreeBSD}/wait.c (62%) rename gen/{ => FreeBSD}/wait3.c (64%) create mode 100644 gen/FreeBSD/waitpid.c create mode 100644 gen/OSSystemInfo.c rename gen/{strchr.c => cache.c} (67%) delete mode 100644 gen/ctime.c delete mode 100644 gen/exec.c delete mode 100644 gen/fstab.c delete mode 100644 gen/getgrouplist.c delete mode 100644 gen/getpass.c delete mode 100644 gen/getvfsent.3 delete mode 100644 gen/glob.c delete mode 100644 gen/hton.c create mode 100644 gen/intro.3 create mode 100644 gen/malloc.3 delete mode 100644 gen/msgctl.3 delete mode 100644 gen/msgget.3 delete mode 100644 gen/msgrcv.3 delete mode 100644 gen/msgsnd.3 delete mode 100644 gen/psignal.c delete mode 100644 gen/pwcache.c delete mode 100644 gen/rcmd.c delete mode 100644 gen/readdir_r.c delete mode 100644 gen/signal.c delete mode 100644 gen/ulimit.c delete mode 100644 gen/waitpid.c delete mode 100644 i386/gen/bcopy_init.c create mode 100644 i386/gen/icacheinval.s delete mode 100644 i386/gen/insque.c delete mode 100644 i386/gen/remque.c create mode 100644 i386/pthreads/Makefile.inc create mode 100644 i386/pthreads/get_cpu_capabilities.s rename ppc/gen/bcmp.c => i386/pthreads/init_cpu_capabilities.c (69%) create mode 100644 i386/pthreads/pthread_getspecific.s rename ppc/sys/ur_cthread.s => i386/pthreads/pthread_self.s (85%) create mode 100644 i386/pthreads/pthread_set_self.s create mode 100644 i386/stdlib/gdtoa.mk create mode 100644 i386/string/Makefile.inc rename {string => i386/string}/strcmp.s (92%) rename i386/sys/{sem_unlink.s => aio_cancel.s} (91%) rename i386/sys/{sem_open.s => aio_error.s} (91%) create mode 100644 i386/sys/aio_fsync.s create mode 100644 i386/sys/aio_read.s create mode 100644 i386/sys/aio_return.s create mode 100644 i386/sys/aio_suspend.s create mode 100644 i386/sys/aio_write.s create mode 100644 i386/sys/audit.s create mode 100644 i386/sys/auditctl.s create mode 100644 i386/sys/auditon.s create mode 100644 i386/sys/auditsvc.s create mode 100644 i386/sys/fhopen.s rename i386/sys/{shm_open.s => fsctl.s} (92%) create mode 100644 i386/sys/getaudit.s create mode 100644 i386/sys/getaudit_addr.s create mode 100644 i386/sys/getauid.s create mode 100644 i386/sys/kevent.s create mode 100644 i386/sys/kqueue.s create mode 100644 i386/sys/kqueue_from_portset_np.s create mode 100644 i386/sys/kqueue_portset_np.s create mode 100644 i386/sys/lio_listio.s create mode 100644 i386/sys/nfsclnt.s create mode 100644 i386/sys/setaudit.s create mode 100644 i386/sys/setaudit_addr.s create mode 100644 i386/sys/setauid.s delete mode 100644 i386/threads/Makefile.inc rename string/rindix.c => include/aio.h (77%) rename string/strchr.c => include/alloca.h (65%) create mode 100644 include/getopt.h create mode 100644 include/iso646.h create mode 100644 include/langinfo.h create mode 100644 include/malloc/Makefile.inc create mode 100644 include/malloc/malloc.h create mode 100644 include/monetary.h delete mode 100644 include/netdb.h create mode 100644 include/nl_types.h create mode 100644 include/readpassphrase.h create mode 100644 include/search.h create mode 100644 include/strhash.h create mode 100644 include/stringlist.h rename gen/difftime.c => include/timeconv.h (62%) create mode 100644 include/wchar.h create mode 100644 include/wctype.h rename locale/{ => FreeBSD}/big5.c (93%) create mode 100644 locale/FreeBSD/big5.c.patch create mode 100644 locale/FreeBSD/btowc.3 create mode 100644 locale/FreeBSD/btowc.c create mode 100644 locale/FreeBSD/collate.c create mode 100644 locale/FreeBSD/collate.c.patch rename locale/{ => FreeBSD}/collate.h (74%) rename locale/{ => FreeBSD}/collcmp.c (95%) rename locale/{ => FreeBSD}/ctype.3 (96%) rename gen/getbootfile.3 => locale/FreeBSD/digittoint.3 (66%) rename locale/{ => FreeBSD}/euc.4 (98%) rename locale/{ => FreeBSD}/euc.c (85%) create mode 100644 locale/FreeBSD/euc.c.patch create mode 100644 locale/FreeBSD/fix_grouping.c rename locale/{ => FreeBSD}/frune.c (88%) rename locale/{ => FreeBSD}/isalnum.3 (91%) rename locale/{ => FreeBSD}/isalpha.3 (90%) rename locale/{ => FreeBSD}/isascii.3 (92%) rename locale/{ => FreeBSD}/isblank.3 (79%) rename locale/{ => FreeBSD}/iscntrl.3 (79%) rename locale/{ => FreeBSD}/isctype.c (81%) rename locale/{ => FreeBSD}/isdigit.3 (80%) rename locale/{ => FreeBSD}/isgraph.3 (89%) rename locale/{ => FreeBSD}/islower.3 (89%) rename locale/{ => FreeBSD}/isprint.3 (90%) rename locale/{ => FreeBSD}/ispunct.3 (88%) rename locale/{ => FreeBSD}/isspace.3 (78%) rename locale/{ => FreeBSD}/isupper.3 (89%) create mode 100644 locale/FreeBSD/iswalnum.3 create mode 100644 locale/FreeBSD/iswctype.c rename locale/{ => FreeBSD}/isxdigit.3 (76%) create mode 100644 locale/FreeBSD/ldpart.c create mode 100644 locale/FreeBSD/ldpart.c.patch create mode 100644 locale/FreeBSD/ldpart.h create mode 100644 locale/FreeBSD/ldpart.h.patch create mode 100644 locale/FreeBSD/lmessages.c create mode 100644 locale/FreeBSD/lmessages.c.patch create mode 100644 locale/FreeBSD/lmessages.h create mode 100644 locale/FreeBSD/lmonetary.c create mode 100644 locale/FreeBSD/lmonetary.c.patch create mode 100644 locale/FreeBSD/lmonetary.h create mode 100644 locale/FreeBSD/lnumeric.c create mode 100644 locale/FreeBSD/lnumeric.c.patch create mode 100644 locale/FreeBSD/lnumeric.h create mode 100644 locale/FreeBSD/localeconv.c create mode 100644 locale/FreeBSD/localeconv.c.patch create mode 100644 locale/FreeBSD/mblen.c create mode 100644 locale/FreeBSD/mbrlen.3 create mode 100644 locale/FreeBSD/mbrlen.c create mode 100644 locale/FreeBSD/mbrtowc.3 create mode 100644 locale/FreeBSD/mbrtowc.c rename locale/{ => FreeBSD}/mbrune.3 (89%) rename locale/{ => FreeBSD}/mbrune.c (90%) create mode 100644 locale/FreeBSD/mbsinit.3 create mode 100644 locale/FreeBSD/mbsinit.c create mode 100644 locale/FreeBSD/mbsrtowcs.3 create mode 100644 locale/FreeBSD/mbsrtowcs.c create mode 100644 locale/FreeBSD/mbstowcs.c create mode 100644 locale/FreeBSD/mbtowc.c rename locale/{ => FreeBSD}/mskanji.c (75%) create mode 100644 locale/FreeBSD/mskanji.c.patch rename locale/{ => FreeBSD}/multibyte.3 (92%) rename locale/{ => FreeBSD}/nl_langinfo.3 (94%) create mode 100644 locale/FreeBSD/nl_langinfo.c create mode 100644 locale/FreeBSD/nl_langinfo.c.patch rename locale/{ => FreeBSD}/nomacros.c (71%) rename locale/{ => FreeBSD}/none.c (88%) rename locale/{ => FreeBSD}/rune.3 (90%) rename locale/{ => FreeBSD}/rune.c (86%) create mode 100644 locale/FreeBSD/rune.c.patch rename locale/{ => FreeBSD}/runetype.c (94%) create mode 100644 locale/FreeBSD/runetype.c.patch rename locale/{ => FreeBSD}/setinvalidrune.c (90%) rename locale/{ => FreeBSD}/setlocale.3 (87%) rename locale/{ => FreeBSD}/setlocale.c (61%) create mode 100644 locale/FreeBSD/setlocale.c.patch rename locale/{ => FreeBSD}/setlocale.h (89%) rename locale/{ => FreeBSD}/setrunelocale.c (55%) rename locale/{ => FreeBSD}/table.c (97%) rename locale/{ => FreeBSD}/toascii.3 (96%) rename locale/{ => FreeBSD}/tolower.3 (87%) rename locale/{ => FreeBSD}/tolower.c (94%) create mode 100644 locale/FreeBSD/tolower.c.patch rename locale/{ => FreeBSD}/toupper.3 (87%) rename locale/{ => FreeBSD}/toupper.c (94%) create mode 100644 locale/FreeBSD/toupper.c.patch rename gen/modf.3 => locale/FreeBSD/towlower.3 (75%) rename gen/ldexp.3 => locale/FreeBSD/towupper.3 (75%) rename locale/{ => FreeBSD}/utf2.4 (93%) rename locale/{ => FreeBSD}/utf2.c (94%) create mode 100644 locale/FreeBSD/utf8.5 create mode 100644 locale/FreeBSD/utf8.c create mode 100644 locale/FreeBSD/utf8.c.patch create mode 100644 locale/FreeBSD/wcrtomb.3 create mode 100644 locale/FreeBSD/wcrtomb.c create mode 100644 locale/FreeBSD/wcsftime.3 create mode 100644 locale/FreeBSD/wcsftime.c create mode 100644 locale/FreeBSD/wcsrtombs.3 create mode 100644 locale/FreeBSD/wcsrtombs.c create mode 100644 locale/FreeBSD/wcstod.3 create mode 100644 locale/FreeBSD/wcstod.c create mode 100644 locale/FreeBSD/wcstof.c create mode 100644 locale/FreeBSD/wcstoimax.c create mode 100644 locale/FreeBSD/wcstol.3 create mode 100644 locale/FreeBSD/wcstol.c create mode 100644 locale/FreeBSD/wcstold.c create mode 100644 locale/FreeBSD/wcstoll.c create mode 100644 locale/FreeBSD/wcstombs.c create mode 100644 locale/FreeBSD/wcstoul.c rename locale/{ansi.c => FreeBSD/wcstoull.c} (52%) create mode 100644 locale/FreeBSD/wcstoumax.c create mode 100644 locale/FreeBSD/wctob.c create mode 100644 locale/FreeBSD/wctomb.c create mode 100644 locale/FreeBSD/wctrans.3 create mode 100644 locale/FreeBSD/wctrans.c create mode 100644 locale/FreeBSD/wctype.3 create mode 100644 locale/FreeBSD/wctype.c create mode 100644 locale/FreeBSD/wcwidth.3 create mode 100644 locale/FreeBSD/wcwidth.c delete mode 100644 locale/collate.c rename i386/sys/shm_unlink.s => mach/headers/task.h (82%) create mode 100644 mach/headers/thread_act.h rename net/{ => FreeBSD}/addr2ascii.3 (94%) create mode 100644 net/FreeBSD/addr2ascii.c create mode 100644 net/FreeBSD/ascii2addr.c rename net/{ => FreeBSD}/inet.3 (95%) rename net/{ => FreeBSD}/inet_addr.c (66%) rename net/{ => FreeBSD}/inet_lnaof.c (67%) rename net/{ => FreeBSD}/inet_makeaddr.c (69%) rename net/{ => FreeBSD}/inet_net.3 (98%) create mode 100644 net/FreeBSD/inet_net_ntop.c create mode 100644 net/FreeBSD/inet_net_pton.c create mode 100644 net/FreeBSD/inet_neta.c rename net/{ => FreeBSD}/inet_netof.c (67%) rename net/{ => FreeBSD}/inet_network.c (64%) rename net/{ => FreeBSD}/inet_ntoa.c (62%) rename net/{ => FreeBSD}/linkaddr.3 (97%) rename net/{ => FreeBSD}/linkaddr.c (74%) create mode 100644 net/FreeBSD/nsap_addr.c create mode 100644 net/FreeBSD/nsap_addr.c.patch rename net/{ => FreeBSD}/recv.c (63%) rename {compat-43 => net/FreeBSD}/send.c (64%) delete mode 100644 net/getaddrinfo.3 delete mode 100644 net/gethostbyname.3 delete mode 100644 net/getifaddrs.3 delete mode 100644 net/getipnodebyname.3 delete mode 100644 net/getnameinfo.3 delete mode 100644 net/getnetent.3 delete mode 100644 net/getprotoent.3 delete mode 100644 net/getservent.3 delete mode 100644 net/if_indextoname.3 delete mode 100644 net/inet6_option_space.3 delete mode 100644 net/inet6_rthdr_space.3 delete mode 100644 net/ns.3 delete mode 100644 net/nsap_addr.c delete mode 100644 net/nsdispatch.3 delete mode 100644 net/rcmd.3 create mode 100644 nls/FreeBSD/catclose.3 create mode 100644 nls/FreeBSD/catgets.3 create mode 100644 nls/FreeBSD/catopen.3 create mode 100644 nls/FreeBSD/msgcat.c create mode 100644 nls/FreeBSD/msgcat.c.patch create mode 100644 nls/FreeBSD/msgcat.h create mode 100644 ppc/gen/icacheinval.s delete mode 100644 ppc/gen/insque.c delete mode 100644 ppc/gen/remque.c delete mode 100644 ppc/gen/strcat.c delete mode 100644 ppc/gen/strcmp.c delete mode 100644 ppc/gen/strcpy.c delete mode 100644 ppc/gen/strncat.c delete mode 100644 ppc/gen/strncmp.c delete mode 100644 ppc/gen/strncpy.c create mode 100644 ppc/pthreads/Makefile.inc create mode 100644 ppc/pthreads/get_cpu_capabilities.s create mode 100644 ppc/pthreads/init_cpu_capabilities.c create mode 100644 ppc/pthreads/pthread_getspecific.s create mode 100644 ppc/pthreads/pthread_self.s rename ppc/{sys/cthread.s => pthreads/pthread_set_self.s} (89%) create mode 100644 ppc/stdlib/gdtoa.mk create mode 100644 ppc/string/Makefile.inc create mode 100644 ppc/string/memcmp.s create mode 100644 ppc/string/strcat.s create mode 100644 ppc/string/strcmp.s create mode 100644 ppc/string/strcpy.s create mode 100644 ppc/string/strlcat.s create mode 100644 ppc/string/strlcpy.s rename ppc/{gen => string}/strlen.s (99%) create mode 100644 ppc/string/strncat.s create mode 100644 ppc/string/strncmp.s create mode 100644 ppc/string/strncpy.s rename ppc/sys/{shm_open.s => aio_cancel.s} (97%) rename ppc/sys/{sem_open.s => aio_error.s} (97%) rename ppc/sys/{shm_unlink.s => aio_fsync.s} (97%) rename ppc/sys/{sem_unlink.s => aio_read.s} (97%) create mode 100644 ppc/sys/aio_return.s create mode 100644 ppc/sys/aio_suspend.s create mode 100644 ppc/sys/aio_write.s create mode 100644 ppc/sys/audit.s create mode 100644 ppc/sys/auditctl.s create mode 100644 ppc/sys/auditon.s create mode 100644 ppc/sys/auditsvc.s create mode 100644 ppc/sys/fhopen.s create mode 100644 ppc/sys/fsctl.s create mode 100644 ppc/sys/getaudit.s create mode 100644 ppc/sys/getaudit_addr.s create mode 100644 ppc/sys/getauid.s create mode 100644 ppc/sys/kevent.s create mode 100644 ppc/sys/kqueue.s create mode 100644 ppc/sys/kqueue_from_portset_np.s create mode 100644 ppc/sys/kqueue_portset_np.s create mode 100644 ppc/sys/lio_listio.s create mode 100644 ppc/sys/nfsclnt.s create mode 100644 ppc/sys/setaudit.s create mode 100644 ppc/sys/setaudit_addr.s create mode 100644 ppc/sys/setauid.s create mode 100644 pthreads/pthread_spinlock.h create mode 100644 regex/FreeBSD/COPYRIGHT create mode 100644 regex/FreeBSD/WHATSNEW create mode 100644 regex/FreeBSD/cclass.h create mode 100644 regex/FreeBSD/cname.h rename regex/{ => FreeBSD}/engine.c (83%) rename regex/{ => FreeBSD}/re_format.7 (99%) rename regex/{ => FreeBSD}/regcomp.c (61%) rename regex/{ => FreeBSD}/regerror.c (64%) rename regex/{ => FreeBSD}/regex.3 (95%) rename regex/{ => FreeBSD}/regex2.h (71%) rename regex/{ => FreeBSD}/regexec.c (75%) create mode 100644 regex/FreeBSD/regexec.c.patch rename regex/{ => FreeBSD}/regfree.c (71%) rename regex/{ => FreeBSD}/utils.h (69%) delete mode 100644 regex/cclass.h delete mode 100644 regex/cname.h create mode 100644 stdio/FreeBSD/_flock_stub.c rename stdio/{ => FreeBSD}/asprintf.c (76%) rename stdio/{ => FreeBSD}/clrerr.c (65%) rename stdio/{ => FreeBSD}/fclose.3 (97%) rename stdio/{ => FreeBSD}/fclose.c (68%) rename stdio/{ => FreeBSD}/fdopen.c (69%) create mode 100644 stdio/FreeBSD/feof.c rename stdio/{ => FreeBSD}/ferror.3 (79%) create mode 100644 stdio/FreeBSD/ferror.c rename stdio/{ => FreeBSD}/fflush.3 (96%) rename stdio/{ => FreeBSD}/fflush.c (65%) create mode 100644 stdio/FreeBSD/fgetc.c rename stdio/{ => FreeBSD}/fgetln.3 (100%) rename stdio/{ => FreeBSD}/fgetln.c (74%) create mode 100644 stdio/FreeBSD/fgetpos.c rename stdio/{ => FreeBSD}/fgets.3 (82%) rename stdio/{ => FreeBSD}/fgets.c (71%) create mode 100644 stdio/FreeBSD/fgetwc.c create mode 100644 stdio/FreeBSD/fgetws.3 create mode 100644 stdio/FreeBSD/fgetws.c create mode 100644 stdio/FreeBSD/fileno.c rename stdio/{ => FreeBSD}/findfp.c (53%) create mode 100644 stdio/FreeBSD/findfp.c.patch rename stdio/{ => FreeBSD}/flags.c (69%) create mode 100644 stdio/FreeBSD/floatio.h create mode 100644 stdio/FreeBSD/flockfile.3 rename stdio/{ => FreeBSD}/fopen.3 (87%) rename stdio/{ => FreeBSD}/fopen.c (69%) create mode 100644 stdio/FreeBSD/fprintf.c create mode 100644 stdio/FreeBSD/fpurge.c rename stdio/{ => FreeBSD}/fputc.c (64%) rename stdio/{ => FreeBSD}/fputs.3 (96%) create mode 100644 stdio/FreeBSD/fputs.3.patch rename stdio/{ => FreeBSD}/fputs.c (66%) create mode 100644 stdio/FreeBSD/fputs.c.patch create mode 100644 stdio/FreeBSD/fputwc.c rename string/strcat.3 => stdio/FreeBSD/fputws.3 (70%) create mode 100644 stdio/FreeBSD/fputws.c rename stdio/{ => FreeBSD}/fread.3 (92%) rename stdio/{ => FreeBSD}/fread.c (70%) rename stdio/{ => FreeBSD}/freopen.c (70%) create mode 100644 stdio/FreeBSD/fscanf.c rename stdio/{ => FreeBSD}/fseek.3 (92%) rename stdio/{ => FreeBSD}/fseek.c (68%) rename stdio/{ => FreeBSD}/fsetpos.c (66%) rename stdio/{ => FreeBSD}/ftell.c (62%) rename stdio/{ => FreeBSD}/funopen.3 (100%) rename stdio/{ => FreeBSD}/funopen.c (70%) rename stdio/{ => FreeBSD}/fvwrite.c (92%) rename stdio/{ => FreeBSD}/fvwrite.h (96%) rename stdlib/rand.c => stdio/FreeBSD/fwalk.c (64%) create mode 100644 stdio/FreeBSD/fwide.3 create mode 100644 stdio/FreeBSD/fwide.c create mode 100644 stdio/FreeBSD/fwprintf.c rename stdio/{ => FreeBSD}/fwrite.c (68%) create mode 100644 stdio/FreeBSD/fwscanf.c rename stdio/{ => FreeBSD}/getc.3 (81%) create mode 100644 stdio/FreeBSD/getc.c rename stdio/{ => FreeBSD}/getchar.c (65%) create mode 100644 stdio/FreeBSD/gets.c rename stdio/{ => FreeBSD}/getw.c (65%) create mode 100644 stdio/FreeBSD/getwc.3 create mode 100644 stdio/FreeBSD/getwc.c create mode 100644 stdio/FreeBSD/getwchar.c rename stdio/{ => FreeBSD}/glue.h (65%) create mode 100644 stdio/FreeBSD/glue.h.patch create mode 100644 stdio/FreeBSD/local.h create mode 100644 stdio/FreeBSD/local.h.patch rename stdio/{ => FreeBSD}/makebuf.c (73%) rename stdio/{ => FreeBSD}/mktemp.3 (98%) rename stdio/{ => FreeBSD}/mktemp.c (80%) rename stdio/{ => FreeBSD}/perror.c (65%) create mode 100644 stdio/FreeBSD/printf.3 create mode 100644 stdio/FreeBSD/printf.3.patch create mode 100644 stdio/FreeBSD/printf.c rename stdio/{ => FreeBSD}/putc.3 (79%) rename stdio/{fgetc.c => FreeBSD/putc.c} (66%) rename stdio/{ => FreeBSD}/putchar.c (64%) rename stdio/{ => FreeBSD}/puts.c (67%) create mode 100644 stdio/FreeBSD/puts.c.patch rename stdio/{ => FreeBSD}/putw.c (66%) rename gen/frexp.3 => stdio/FreeBSD/putwc.3 (63%) create mode 100644 stdio/FreeBSD/putwc.c create mode 100644 stdio/FreeBSD/putwchar.c rename stdio/{ => FreeBSD}/refill.c (72%) rename stdio/{ => FreeBSD}/remove.3 (100%) rename stdio/{ => FreeBSD}/remove.c (94%) create mode 100644 stdio/FreeBSD/rewind.c rename stdio/{ => FreeBSD}/rget.c (66%) rename stdio/{ => FreeBSD}/scanf.3 (69%) create mode 100644 stdio/FreeBSD/scanf.c rename stdio/{ => FreeBSD}/setbuf.3 (93%) rename stdio/{ => FreeBSD}/setbuf.c (64%) rename stdio/{ => FreeBSD}/setbuffer.c (65%) rename stdio/{ => FreeBSD}/setvbuf.c (78%) create mode 100644 stdio/FreeBSD/snprintf.c create mode 100644 stdio/FreeBSD/sprintf.c rename stdio/{ => FreeBSD}/sscanf.c (65%) create mode 100644 stdio/FreeBSD/sscanf.c.patch rename stdio/{ => FreeBSD}/stdio.3 (86%) rename stdio/{ => FreeBSD}/stdio.c (52%) create mode 100644 stdio/FreeBSD/swprintf.c create mode 100644 stdio/FreeBSD/swscanf.c rename stdio/{ => FreeBSD}/tempnam.c (68%) rename stdio/{ => FreeBSD}/tmpfile.c (63%) rename stdio/{ => FreeBSD}/tmpnam.3 (81%) rename stdio/{ => FreeBSD}/tmpnam.c (64%) rename stdio/{ => FreeBSD}/ungetc.3 (96%) rename stdio/{ => FreeBSD}/ungetc.c (77%) create mode 100644 stdio/FreeBSD/ungetwc.3 create mode 100644 stdio/FreeBSD/ungetwc.c create mode 100644 stdio/FreeBSD/unlocked.c rename stdio/{ => FreeBSD}/vasprintf.c (83%) rename stdio/{ => FreeBSD}/vfprintf.c (50%) create mode 100644 stdio/FreeBSD/vfprintf.c.patch rename stdio/{ => FreeBSD}/vfscanf.c (53%) create mode 100644 stdio/FreeBSD/vfwprintf.c create mode 100644 stdio/FreeBSD/vfwprintf.c.patch create mode 100644 stdio/FreeBSD/vfwscanf.c rename stdio/{ => FreeBSD}/vprintf.c (64%) rename stdio/{ => FreeBSD}/vscanf.c (63%) create mode 100644 stdio/FreeBSD/vsnprintf.c rename stdio/{ => FreeBSD}/vsprintf.c (64%) rename stdio/{ => FreeBSD}/vsscanf.c (67%) create mode 100644 stdio/FreeBSD/vswprintf.c create mode 100644 stdio/FreeBSD/vswscanf.c create mode 100644 stdio/FreeBSD/vwprintf.c create mode 100644 stdio/FreeBSD/vwscanf.c rename stdio/{ => FreeBSD}/wbuf.c (73%) rename stdio/{printf.3 => FreeBSD/wprintf.3} (57%) create mode 100644 stdio/FreeBSD/wprintf.3.patch create mode 100644 stdio/FreeBSD/wprintf.c create mode 100644 stdio/FreeBSD/wscanf.3 create mode 100644 stdio/FreeBSD/wscanf.c rename stdio/{ => FreeBSD}/wsetup.c (73%) delete mode 100644 stdio/feof.c delete mode 100644 stdio/ferror.c delete mode 100644 stdio/fgetpos.c delete mode 100644 stdio/fileno.c delete mode 100644 stdio/floatio.h delete mode 100644 stdio/fprintf.c delete mode 100644 stdio/fpurge.c delete mode 100644 stdio/fscanf.c delete mode 100644 stdio/fwalk.c delete mode 100644 stdio/getc.c delete mode 100644 stdio/gets.c create mode 100644 stdio/hexfloat.c delete mode 100644 stdio/printf.c delete mode 100644 stdio/putc.c delete mode 100644 stdio/rewind.c delete mode 100644 stdio/scanf.c delete mode 100644 stdio/snprintf.c delete mode 100644 stdio/sprintf.c delete mode 100644 stdio/vsnprintf.c create mode 100644 stdlib/FreeBSD/_Exit_.c rename stdlib/{ => FreeBSD}/abort.3 (100%) create mode 100644 stdlib/FreeBSD/abort.c create mode 100644 stdlib/FreeBSD/abort.c.patch rename stdlib/{ => FreeBSD}/abs.3 (94%) rename {i386/gen => stdlib/FreeBSD}/abs.c (63%) rename stdlib/{ => FreeBSD}/alloca.3 (100%) create mode 100644 stdlib/FreeBSD/alloca.3.patch rename stdlib/{ => FreeBSD}/atexit.3 (86%) rename stdlib/{ => FreeBSD}/atexit.c (65%) rename stdlib/{ => FreeBSD}/atexit.h (64%) rename stdlib/{ => FreeBSD}/atof.3 (94%) rename stdlib/{ => FreeBSD}/atof.c (63%) rename stdlib/{ => FreeBSD}/atoi.3 (94%) rename stdlib/{ => FreeBSD}/atoi.c (62%) rename stdlib/{ => FreeBSD}/atol.3 (79%) rename stdlib/{ => FreeBSD}/atol.c (62%) create mode 100644 stdlib/FreeBSD/atoll.c rename stdlib/{ => FreeBSD}/bsearch.3 (100%) rename stdlib/{ => FreeBSD}/bsearch.c (70%) rename stdlib/{ => FreeBSD}/div.3 (93%) rename stdlib/{ => FreeBSD}/div.c (74%) rename stdlib/{ => FreeBSD}/exit.3 (67%) rename stdlib/{ => FreeBSD}/exit.c (65%) create mode 100644 stdlib/FreeBSD/exit.c.patch rename stdlib/{ => FreeBSD}/getenv.3 (95%) rename stdlib/{ => FreeBSD}/getenv.c (65%) create mode 100644 stdlib/FreeBSD/getenv.c.patch rename stdlib/{ => FreeBSD}/getopt.3 (98%) rename stdlib/{ => FreeBSD}/getopt.c (72%) create mode 100644 stdlib/FreeBSD/getopt_long.3 create mode 100644 stdlib/FreeBSD/getopt_long.c rename stdlib/{ => FreeBSD}/getsubopt.3 (100%) rename stdlib/{ => FreeBSD}/getsubopt.c (72%) create mode 100644 stdlib/FreeBSD/grantpt.3 create mode 100644 stdlib/FreeBSD/grantpt.c rename stdlib/{ => FreeBSD}/hcreate.3 (88%) create mode 100644 stdlib/FreeBSD/hcreate.c rename stdlib/{ => FreeBSD}/heapsort.c (83%) create mode 100644 stdlib/FreeBSD/imaxabs.3 create mode 100644 stdlib/FreeBSD/imaxabs.c create mode 100644 stdlib/FreeBSD/imaxdiv.3 create mode 100644 stdlib/FreeBSD/imaxdiv.c create mode 100644 stdlib/FreeBSD/insque.3 create mode 100644 stdlib/FreeBSD/insque.c rename stdlib/{ => FreeBSD}/labs.3 (94%) rename stdlib/{ => FreeBSD}/labs.c (65%) rename stdlib/{ => FreeBSD}/ldiv.3 (92%) rename stdlib/{ => FreeBSD}/ldiv.c (67%) create mode 100644 stdlib/FreeBSD/llabs.3 create mode 100644 stdlib/FreeBSD/llabs.c create mode 100644 stdlib/FreeBSD/lldiv.3 create mode 100644 stdlib/FreeBSD/lldiv.c create mode 100644 stdlib/FreeBSD/lsearch.3 create mode 100644 stdlib/FreeBSD/lsearch.c rename stdlib/{ => FreeBSD}/memory.3 (100%) rename stdlib/{ => FreeBSD}/merge.c (84%) rename stdlib/{ => FreeBSD}/putenv.c (66%) rename stdlib/{ => FreeBSD}/qsort.3 (78%) rename stdlib/{ => FreeBSD}/qsort.c (62%) create mode 100644 stdlib/FreeBSD/qsort_r.c create mode 100644 stdlib/FreeBSD/qsort_r.c.patch rename stdlib/{ => FreeBSD}/radixsort.3 (100%) rename stdlib/{ => FreeBSD}/radixsort.c (80%) rename stdlib/{ => FreeBSD}/rand.3 (97%) create mode 100644 stdlib/FreeBSD/rand.c rename stdlib/{ => FreeBSD}/random.3 (100%) rename stdlib/{ => FreeBSD}/random.c (74%) rename stdlib/{ => FreeBSD}/reallocf.c (92%) rename stdlib/{ => FreeBSD}/realpath.3 (93%) create mode 100644 stdlib/FreeBSD/realpath.c create mode 100644 stdlib/FreeBSD/remque.c rename stdlib/{ => FreeBSD}/setenv.c (61%) create mode 100644 stdlib/FreeBSD/setenv.c.patch rename stdlib/{ => FreeBSD}/strfmon.3 (55%) create mode 100644 stdlib/FreeBSD/strfmon.3.patch create mode 100644 stdlib/FreeBSD/strfmon.c create mode 100644 stdlib/FreeBSD/strhash.c rename stdlib/{ => FreeBSD}/strtod.3 (51%) create mode 100644 stdlib/FreeBSD/strtoimax.c rename stdlib/{ => FreeBSD}/strtol.3 (76%) rename stdlib/{ => FreeBSD}/strtol.c (65%) rename stdlib/{ => FreeBSD}/strtoll.c (82%) rename stdlib/{ => FreeBSD}/strtoq.c (85%) rename stdlib/{ => FreeBSD}/strtoul.3 (81%) rename stdlib/{ => FreeBSD}/strtoul.c (59%) rename stdlib/{ => FreeBSD}/strtoull.c (77%) create mode 100644 stdlib/FreeBSD/strtoumax.c rename stdlib/{ => FreeBSD}/strtouq.c (85%) rename stdlib/{ => FreeBSD}/system.3 (96%) rename stdlib/{ => FreeBSD}/system.c (57%) create mode 100644 stdlib/FreeBSD/tdelete.c create mode 100644 stdlib/FreeBSD/tfind.c rename stdlib/{ => FreeBSD}/tsearch.3 (89%) create mode 100644 stdlib/FreeBSD/tsearch.c create mode 100644 stdlib/FreeBSD/twalk.c delete mode 100644 stdlib/abort.c delete mode 100644 stdlib/malloc.3 delete mode 100644 stdlib/strtod.c rename stdtime/{ => FreeBSD}/asctime.c (80%) rename stdtime/{ => FreeBSD}/ctime.3 (97%) rename stdtime/{ => FreeBSD}/difftime.c (90%) rename stdtime/{ => FreeBSD}/localtime.c (83%) create mode 100644 stdtime/FreeBSD/localtime.c.patch rename stdtime/{ => FreeBSD}/private.h (93%) rename stdtime/{ => FreeBSD}/strftime.3 (90%) rename stdtime/{ => FreeBSD}/strftime.c (88%) rename stdtime/{ => FreeBSD}/strptime.3 (83%) rename stdtime/{ => FreeBSD}/strptime.c (80%) rename stdtime/{ => FreeBSD}/time2posix.3 (97%) create mode 100644 stdtime/FreeBSD/time2posix.3.patch create mode 100644 stdtime/FreeBSD/time32.c create mode 100644 stdtime/FreeBSD/timelocal.c create mode 100644 stdtime/FreeBSD/timelocal.c.patch rename stdtime/{ => FreeBSD}/timelocal.h (68%) rename stdtime/{ => FreeBSD}/tzfile.5 (97%) rename stdtime/{ => FreeBSD}/tzfile.h (98%) delete mode 100644 stdtime/timelocal.c rename string/{ => FreeBSD}/bcmp.3 (92%) rename {i386/gen => string/FreeBSD}/bcmp.c (61%) rename string/{ => FreeBSD}/bcopy.3 (91%) create mode 100644 string/FreeBSD/bcopy.c rename string/{ => FreeBSD}/bstring.3 (100%) rename string/{ => FreeBSD}/bzero.3 (91%) create mode 100644 string/FreeBSD/bzero.c create mode 100644 string/FreeBSD/bzero.c.patch rename string/{ => FreeBSD}/ffs.3 (91%) rename {i386/gen => string/FreeBSD}/ffs.c (62%) rename string/{ => FreeBSD}/index.3 (92%) rename string/{ => FreeBSD}/index.c (62%) rename string/{ => FreeBSD}/memccpy.3 (100%) rename string/{ => FreeBSD}/memccpy.c (63%) rename string/{ => FreeBSD}/memchr.3 (100%) rename string/{ => FreeBSD}/memchr.c (66%) rename string/{ => FreeBSD}/memcmp.3 (100%) rename string/{ => FreeBSD}/memcmp.c (64%) rename string/{ => FreeBSD}/memcpy.3 (94%) create mode 100644 string/FreeBSD/memcpy.3.patch create mode 100644 string/FreeBSD/memcpy.c create mode 100644 string/FreeBSD/memcpy.c.patch rename string/{ => FreeBSD}/memmove.3 (100%) create mode 100644 string/FreeBSD/memmove.c create mode 100644 string/FreeBSD/memmove.c.patch rename string/{ => FreeBSD}/memset.3 (100%) rename string/{ => FreeBSD}/memset.c (72%) rename string/{ => FreeBSD}/rindex.3 (92%) rename string/{ => FreeBSD}/rindex.c (61%) create mode 100644 string/FreeBSD/stpcpy.c rename string/{ => FreeBSD}/strcasecmp.3 (92%) create mode 100644 string/FreeBSD/strcasecmp.c create mode 100644 string/FreeBSD/strcasestr.c create mode 100644 string/FreeBSD/strcat.3 rename {i386/gen => string/FreeBSD}/strcat.c (61%) rename string/{ => FreeBSD}/strchr.3 (96%) create mode 100644 string/FreeBSD/strchr.c create mode 100644 string/FreeBSD/strchr.c.patch rename string/{ => FreeBSD}/strcmp.3 (100%) rename {i386/gen => string/FreeBSD}/strcmp.c (63%) rename string/{ => FreeBSD}/strcoll.3 (96%) create mode 100644 string/FreeBSD/strcoll.c rename string/{ => FreeBSD}/strcpy.3 (77%) rename {i386/gen => string/FreeBSD}/strcpy.c (61%) rename string/{ => FreeBSD}/strcspn.3 (100%) rename string/{ => FreeBSD}/strcspn.c (67%) rename string/{ => FreeBSD}/strdup.3 (100%) rename string/{ => FreeBSD}/strdup.c (63%) rename string/{ => FreeBSD}/strerror.3 (73%) create mode 100644 string/FreeBSD/strerror.c rename string/{ => FreeBSD}/string.3 (96%) rename string/{ => FreeBSD}/strlcat.c (85%) rename string/{ => FreeBSD}/strlcpy.3 (98%) rename string/{ => FreeBSD}/strlcpy.c (90%) rename string/{ => FreeBSD}/strlen.3 (100%) rename {i386/gen => string/FreeBSD}/strlen.c (63%) rename string/{ => FreeBSD}/strmode.3 (100%) rename string/{ => FreeBSD}/strmode.c (76%) rename {i386/gen => string/FreeBSD}/strncat.c (64%) rename {i386/gen => string/FreeBSD}/strncmp.c (62%) rename {i386/gen => string/FreeBSD}/strncpy.c (64%) create mode 100644 string/FreeBSD/strnstr.c rename string/{ => FreeBSD}/strpbrk.3 (100%) rename string/{ => FreeBSD}/strpbrk.c (65%) rename string/{ => FreeBSD}/strrchr.3 (100%) create mode 100644 string/FreeBSD/strrchr.c create mode 100644 string/FreeBSD/strrchr.c.patch rename string/{ => FreeBSD}/strsep.3 (93%) rename string/{ => FreeBSD}/strsep.c (69%) create mode 100644 string/FreeBSD/strsignal.c create mode 100644 string/FreeBSD/strsignal.c.patch rename string/{ => FreeBSD}/strspn.3 (100%) rename string/{ => FreeBSD}/strspn.c (65%) rename string/{ => FreeBSD}/strstr.3 (94%) rename string/{ => FreeBSD}/strstr.c (66%) rename string/{ => FreeBSD}/strtok.3 (97%) rename string/{ => FreeBSD}/strtok.c (53%) rename string/{ => FreeBSD}/strxfrm.3 (94%) create mode 100644 string/FreeBSD/strxfrm.c rename string/{ => FreeBSD}/swab.3 (93%) rename string/{ => FreeBSD}/swab.c (62%) create mode 100644 string/FreeBSD/wcscat.c create mode 100644 string/FreeBSD/wcschr.c create mode 100644 string/FreeBSD/wcscmp.c create mode 100644 string/FreeBSD/wcscoll.3 create mode 100644 string/FreeBSD/wcscoll.c create mode 100644 string/FreeBSD/wcscpy.c create mode 100644 string/FreeBSD/wcscspn.c create mode 100644 string/FreeBSD/wcslcat.c create mode 100644 string/FreeBSD/wcslcpy.c create mode 100644 string/FreeBSD/wcslen.c create mode 100644 string/FreeBSD/wcsncat.c create mode 100644 string/FreeBSD/wcsncmp.c create mode 100644 string/FreeBSD/wcsncpy.c create mode 100644 string/FreeBSD/wcspbrk.c create mode 100644 string/FreeBSD/wcsrchr.c create mode 100644 string/FreeBSD/wcsspn.c create mode 100644 string/FreeBSD/wcsstr.c create mode 100644 string/FreeBSD/wcstok.3 create mode 100644 string/FreeBSD/wcstok.c rename gen/rfork_thread.3 => string/FreeBSD/wcswidth.3 (54%) create mode 100644 string/FreeBSD/wcswidth.c create mode 100644 string/FreeBSD/wcsxfrm.3 create mode 100644 string/FreeBSD/wcsxfrm.c rename string/{ => FreeBSD}/wmemchr.3 (89%) create mode 100644 string/FreeBSD/wmemchr.c create mode 100644 string/FreeBSD/wmemcmp.c create mode 100644 string/FreeBSD/wmemcpy.c create mode 100644 string/FreeBSD/wmemmove.c create mode 100644 string/FreeBSD/wmemset.c delete mode 100644 string/strcasecmp.c delete mode 100644 string/strcoll.c delete mode 100644 string/strerror.c delete mode 100644 string/strftime.c delete mode 100644 string/strxfrm.c create mode 100644 sys/fix-3375657.c create mode 100644 sys/sem_open.c rename gen/sleep.c => sys/sem_unlink.c (55%) create mode 100644 sys/shm_open.c rename i386/threads/thread.c => sys/shm_unlink.c (54%) create mode 100644 util/fparseln.3 create mode 100644 util/fparseln.c create mode 100644 util/opendev.3 create mode 100644 util/opendev.c diff --git a/CLIB-LIST b/CLIB-LIST index 7b30a40..a7cd26f 100644 --- a/CLIB-LIST +++ b/CLIB-LIST @@ -64,6 +64,9 @@ bypot bzero cabs calloc +catclose +catgets +catopen cbreak cbrt ceil diff --git a/GNUmakefile b/GNUmakefile index 36f4c91..4e75674 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -10,6 +10,7 @@ ifndef RC_i386 RC_ppc = 1 endif endif +BSDMAKE = bsdmake -j 2 # Remove the arch stuff, since we know better here. LOCAL_CFLAGS = $(filter-out -arch ppc -arch i386,$(RC_CFLAGS)) @@ -47,7 +48,7 @@ endif build-man: MAKEOBJDIR="$(OBJROOT)" MACHINE_ARCH="$(shell arch)" \ - MAKEFLAGS="" bsdmake buildman + MAKEFLAGS="" $(BSDMAKE) buildman build-static: build-ppc-static build-i386-static @echo "Checking for libc_static.a" @if [ -f "$(OBJROOT)/obj.ppc/libc_static.a" -a -f "$(OBJROOT)/obj.i386/libc_static.a" ]; then\ @@ -98,68 +99,79 @@ build-ppc-static: @if [ ! -z "$(RC_ppc)" ]; then \ mkdir -p $(OBJROOT)/obj.ppc ; \ MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \ - MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" bsdmake libc_static.a;\ + MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc_static.a;\ fi build-i386-static: @if [ ! -z "$(RC_i386)" ]; then \ mkdir -p $(OBJROOT)/obj.i386 ; \ MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \ - MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" bsdmake libc_static.a;\ + MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" $(BSDMAKE) libc_static.a;\ fi build-ppc-profile: @if [ ! -z "$(RC_ppc)" ]; then \ mkdir -p $(OBJROOT)/obj.ppc ; \ MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \ - MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" bsdmake libc_profile.a;\ + MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc_profile.a;\ fi build-i386-profile: @if [ ! -z "$(RC_i386)" ]; then \ mkdir -p $(OBJROOT)/obj.i386 ; \ MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \ - MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" bsdmake libc_profile.a;\ + MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" $(BSDMAKE) libc_profile.a;\ fi build-ppc-debug: @if [ ! -z "$(RC_ppc)" ]; then \ mkdir -p $(OBJROOT)/obj.ppc ; \ MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \ - MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" bsdmake libc_debug.a;\ + MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc_debug.a;\ fi build-i386-debug: @if [ ! -z "$(RC_i386)" ]; then \ mkdir -p $(OBJROOT)/obj.i386 ; \ MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \ - MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" bsdmake libc_debug.a;\ + MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" $(BSDMAKE) libc_debug.a;\ fi build-ppc-dynamic: @if [ ! -z "$(RC_ppc)" ]; then \ mkdir -p $(OBJROOT)/obj.ppc ; \ MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \ - MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" bsdmake libc.a;\ + MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc.a;\ fi build-i386-dynamic: @if [ ! -z "$(RC_i386)" ]; then \ mkdir -p $(OBJROOT)/obj.i386 ; \ MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \ - MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" bsdmake libc.a;\ + MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" $(BSDMAKE) libc.a;\ fi build-ppc: @if [ ! -z "$(RC_ppc)" ]; then \ mkdir -p $(OBJROOT)/obj.ppc ; \ MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \ - MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" bsdmake build;\ + MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) build;\ fi build-i386: @if [ ! -z "$(RC_i386)" ]; then \ mkdir -p $(OBJROOT)/obj.i386 ; \ MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \ - MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" bsdmake build;\ + MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" $(BSDMAKE) build;\ fi installsrc: $(_v) pax -rw . "$(SRCROOT)" + installhdrs-real: - MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" \ - MACHINE_ARCH="$(shell arch)" MAKEFLAGS="" bsdmake installhdrs + MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" MAKEFLAGS="" \ + $(BSDMAKE) installhdrs + @if [ ! -z "$(RC_i386)" ]; then \ + mkdir -p "$(OBJROOT)/obj.i386" ; \ + MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \ + MAKEFLAGS="" $(BSDMAKE) installhdrs-md ; \ + fi + @if [ ! -z "$(RC_ppc)" ]; then \ + mkdir -p "$(OBJROOT)/obj.ppc" ; \ + MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \ + MAKEFLAGS="" $(BSDMAKE) installhdrs-md ; \ + fi BI-install-static: build-static mkdir -p $(DSTROOT)/usr/local/lib/system @@ -194,6 +206,7 @@ BI-install-dynamic: build-dynamic ranlib "$(DSTROOT)/usr/local/lib/system/libc.a"; \ fi +# Don't use -j here; it may try to make links before the files are copied install-man: mkdir -p $(DSTROOT)/usr/share/man/man2 mkdir -p $(DSTROOT)/usr/share/man/man3 @@ -201,7 +214,7 @@ install-man: mkdir -p $(DSTROOT)/usr/share/man/man5 mkdir -p $(DSTROOT)/usr/share/man/man7 MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" NOMANCOMPRESS=1 \ - MACHINE_ARCH="$(shell arch)" MAKEFLAGS="" bsdmake maninstall + MACHINE_ARCH="$(shell arch)" MAKEFLAGS="" bsdmake fbsdman maninstall install-all: build install-man BI-install-dynamic BI-install-static BI-install-profile diff --git a/Makefile b/Makefile index 069ccc4..0647549 100644 --- a/Makefile +++ b/Makefile @@ -12,16 +12,23 @@ LIB=c SHLIB_MAJOR= 1 SHLIB_MINOR= 0 +CC_3_3_OR_GREATER != ${.CURDIR}/cc-3.3-or-greater +.if (${CC_3_3_OR_GREATER} != YES) +CC = gcc-3.3 +.endif .if (${MACHINE_ARCH} == unknown) -MACHINE_ARCH = ppc +MACHINE_ARCH != /usr/bin/arch .endif .if (${MACHINE_ARCH} == ppc) CFLAGS += -faltivec -DALTIVEC .endif -CFLAGS += -DNOID -DALL_STATE -I${.CURDIR}/include -I${.CURDIR}/include/objc +CFLAGS += -DNOID -I${.CURDIR}/include -I${.CURDIR}/include/objc +PRIVINC = ${NEXT_ROOT}/System/Library/Frameworks/System.framework/PrivateHeaders +CFLAGS += -I${PRIVINC} CFLAGS += -DLIBC_MAJOR=${SHLIB_MAJOR} -no-cpp-precomp -force_cpusubtype_ALL CFLAGS += -arch ${MACHINE_ARCH} -fno-common -pipe -Wmost -g -CFLAGS += -finline-limit=5000 +CFLAGS += -finline-limit=5000 -D__FBSDID=__RCSID -Wno-long-double +CFLAGS += -D__APPLE_PR3275149_HACK__ AINC= -I${.CURDIR}/${MACHINE_ARCH} -no-cpp-precomp -force_cpusubtype_ALL AINC+=-arch ${MACHINE_ARCH} -g CLEANFILES+=tags diff --git a/Makefile.fbsd_begin b/Makefile.fbsd_begin new file mode 100644 index 0000000..5f996f0 --- /dev/null +++ b/Makefile.fbsd_begin @@ -0,0 +1,24 @@ +# For the FreeBSD auto patching mechanism and compatibility environment +# setup, original FreeBSD sources a put into a FreeBSD subdirectory. +# If a file with the same name, but suffix ".patch" is in that directory, +# that patch will be applied before use. +# +# The FBSD* variables are set, and bracketed by .include of Makefile.fbsd_begin +# and Makefile.fbsd_end +# +# Define (empty) variables so that make doesn't give substitution +# errors if the included makefiles don't change these: + +FBSDMAN1= +FBSDMAN2= +FBSDMAN3= +FBSDMAN4= +FBSDMAN5= +FBSDMAN6= +FBSDMAN7= +FBSDMAN8= +FBSDMAN9= +FBSDMDSRCS= +FBSDMISRCS= +FBSDORIGHDRS= +FBSDSRCS= diff --git a/Makefile.fbsd_end b/Makefile.fbsd_end new file mode 100644 index 0000000..835bd0d --- /dev/null +++ b/Makefile.fbsd_end @@ -0,0 +1,59 @@ +# For the FreeBSD auto patching mechanism and compatibility environment +# setup, original FreeBSD sources a put into a FreeBSD subdirectory. +# If a file with the same name, but suffix ".patch" is in that directory, +# that patch will be applied before use. +# +# The FBSDMDSRCS, FBSDMISRCS, FBSDORIGHDRS and FBSDSRCS variables must be set, +# and bracketed by .include of Makefile.fbsd_begin and Makefile.fbsd_end +# +# Set up dependencies between the FreeBSD source (in a FreeBSD subdirectory) +# and a file with a -fbsd.x suffix (where x is 'c' or 's'). The suffix +# rules will then compile the file with the simulate FreeBSD environment. + +FBSDSECTIONS= 1 2 3 4 5 6 7 8 9 + +.if !target(_FBSDPATCH) +_FBSDPATCH: .USE + @if [ -f ${.ALLSRC}.patch ]; then \ + echo cp ${.ALLSRC} ${.TARGET}; \ + cp ${.ALLSRC} ${.TARGET}; \ + echo patch ${.TARGET} ${.ALLSRC}.patch; \ + patch ${.TARGET} ${.ALLSRC}.patch; \ + else \ + echo ln -s ${.ALLSRC} ${.TARGET}; \ + ln -s ${.ALLSRC} ${.TARGET}; \ + fi +.endif +.if !target(_FBSDPATCH) +_FBSDPATCH: .USE + cp ${.ALLSRC} ${.TARGET}; \ + patch ${.TARGET} ${.ALLSRC}.patch +.endif + +.for _src in ${FBSDSRCS} +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _FBSDPATCH +SRCS+= ${_src} +.endfor + +.for _src in ${FBSDMDSRCS} +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _FBSDPATCH +MDSRCS+= ${_src} +.endfor + +.for _src in ${FBSDMISRCS} +${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _FBSDPATCH +MISRCS+= ${_src} +.endfor + +.for _src in ${FBSDORIGHDRS} +${_src}: FreeBSD/${_src} _FBSDPATCH +FBSDHDRS+= ${_src} +.endfor + +.for _sect in ${FBSDSECTIONS} +.for _src in ${FBSDMAN${_sect}} +${_src}: FreeBSD/${_src} _FBSDPATCH +MAN${_sect}+= ${_src} +FBSDPATCHMAN+= ${_src} +.endfor +.endfor diff --git a/Makefile.inc b/Makefile.inc index e05962e..b739e28 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -10,6 +10,15 @@ MDASM= MIASM= NOASM= +# SUPPRESSSRCS is used to prevent machine-independent files from being +# built, when a machine-dependent file defines multiple symbols. +# Use MDSRCS to block one file, and SUPPRESSSRCS to block the others. +SUPPRESSSRCS= + +# Variable needed by the FreeBSD auto-patching mechanism +FBSDHDRS= +FBSDPATCHMAN= + # # If there is a machine dependent makefile, use it: # @@ -19,6 +28,7 @@ NOASM= .include "${.CURDIR}/db/Makefile.inc" .include "${.CURDIR}/compat-43/Makefile.inc" +.include "${.CURDIR}/gdtoa/Makefile.inc" .include "${.CURDIR}/gen/Makefile.inc" .include "${.CURDIR}/gmon/Makefile.inc" .include "${.CURDIR}/include/Makefile.inc" @@ -26,7 +36,7 @@ NOASM= .include "${.CURDIR}/locale/Makefile.inc" .include "${.CURDIR}/mach/Makefile.inc" .include "${.CURDIR}/net/Makefile.inc" -#.include "${.CURDIR}/nls/Makefile.inc" +.include "${.CURDIR}/nls/Makefile.inc" #.include "${.CURDIR}/posix1e/Makefile.inc" .include "${.CURDIR}/pthreads/Makefile.inc" .if !defined(NO_QUAD) @@ -56,10 +66,11 @@ CFLAGS+= -DHESIOD SRCS+= ${MISRCS} .else # Append machine-dependent sources, then append machine-independent sources -# for which there is no machine-dependent variant. +# for which there is no machine-dependent variant, and not being suppressed. SRCS+= ${MDSRCS} +_SUPPRESS= ${MDSRCS} ${SUPPRESSSRCS} .for _src in ${MISRCS} -.if ${MDSRCS:R:M${_src:R}} == "" +.if ${_SUPPRESS:R:M${_src:R}} == "" SRCS+= ${_src} .endif .endfor diff --git a/Makefile.xbs b/Makefile.xbs index 7409a24..70ac4fa 100644 --- a/Makefile.xbs +++ b/Makefile.xbs @@ -23,60 +23,85 @@ .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 maninstall + install_libc_profile.a install_libc_debug.a fbsdman maninstall .SUFFIXES: -.SUFFIXES: .o .po .So .do .S .s .c .cc .cpp .cxx .m .C .f .y .l .defs .h +.SUFFIXES: .o .po .So .do .S .s -fbsd.c .c .cc .cpp .cxx .m .C .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 OBJS+= ${SRCS:N*.h:R:S/$/.o/g} POBJS+= ${OBJS:.o=.po} ${STATICOBJS:.o=.po} SOBJS+= ${OBJS:.o=.So} +FBSDFLAGS= -I${.CURDIR}/fbsdcompat -include _fbsd_compat_.h -.c.o: - ${CC} -static ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.c.po: +-fbsd.c.o: + ${CC} -static ${FBSDFLAGS} ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET} +.c.o User.cUser.o Server.cServer.o: + ${CC} -static ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET} +-fbsd.c.po: + ${CC} -pg -DPROFILE ${FBSDFLAGS} ${CFLAGS} -Os -c ${.IMPSRC} \ + -o ${.TARGET} +.c.po User.cUser.po Server.cServer.po: ${CC} -pg -DPROFILE ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET} -.c.So: +-fbsd.c.So: + ${CC} ${FBSDFLAGS} ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET} +.c.So User.cUser.So Server.cServer.So: ${CC} ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET} -.c.do: +-fbsd.c.do: + ${CC} -g -DDEBUG ${FBSDFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} +.c.do User.cUser.do Server.cServer.do: ${CC} -g -DDEBUG ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} +-fbsd.s.o: + ${CC} -x assembler-with-cpp ${FBSDFLAGS} ${CFLAGS:M-[BID]*} \ + -static ${AINC} -c ${.IMPSRC} -o ${.TARGET} .s.o: ${CC} -x assembler-with-cpp ${CFLAGS:M-[BID]*} -static ${AINC} -c \ - ${.IMPSRC} -o ${.TARGET} + ${.IMPSRC} -o ${.TARGET} +-fbsd.s.po: + ${CC} -pg -DPROFILE -x assembler-with-cpp ${FBSDFLAGS} \ + ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET} .s.po: ${CC} -pg -DPROFILE -x assembler-with-cpp ${CFLAGS:M-[BID]*} -Os \ - ${AINC} -c ${.IMPSRC} -o ${.TARGET} + ${AINC} -c ${.IMPSRC} -o ${.TARGET} +-fbsd.s.So: + ${CC} -x assembler-with-cpp ${FBSDFLAGS} \ + ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET} .s.So: ${CC} -x assembler-with-cpp \ - ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET} + ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET} +-fbsd.s.do: + ${CC} -DDEBUG -g -x assembler-with-cpp ${FBSDFLAGS} ${CFLAGS:M-[BID]*} \ + ${AINC} -c ${.IMPSRC} -o ${.TARGET} .s.do: ${CC} -DDEBUG -g -x assembler-with-cpp ${CFLAGS:M-[BID]*} ${AINC} -c \ - ${.IMPSRC} -o ${.TARGET} -.defs.h: - mig -user ${.TARGET:S/.h$/User.c/} \ - -server ${.TARGET:S/.h$/Server.c/} -header ${.TARGET} ${.IMPSRC} + ${.IMPSRC} -o ${.TARGET} +.defs.h .defsUser.c .defsServer.c: + mig -arch ${MACHINE_ARCH} -user ${.PREFIX}User.c -server ${.PREFIX}Server.c -header ${.PREFIX}.h ${.IMPSRC} -gen_mig_defs: ${SRVMIGHDRS} ${MIGHDRS} -lib${LIB}_static.a:: ${OBJS} ${STATICOBJS} +gen_mig_defs: ${SRVMIGHDRS} ${MIGHDRS} +gen_md_mig_defs: ${MD_MIGHDRS} + +lib${LIB}_static.a:: ${FBSDHDRS} ${OBJS} ${STATICOBJS} @${ECHO} building static ${LIB} library @rm -f lib${LIB}_static.a @${AR} cq lib${LIB}_static.a `lorder ${OBJS} ${STATICOBJS} | tsort -q` ${ARADD} ${RANLIB} lib${LIB}_static.a -lib${LIB}_profile.a:: ${POBJS} +lib${LIB}_profile.a:: ${FBSDHDRS} ${POBJS} @${ECHO} building profiled ${LIB} library @rm -f lib${LIB}_profile.a @${AR} cq lib${LIB}_profile.a `lorder ${POBJS} | tsort -q` ${ARADD} ${RANLIB} lib${LIB}_profile.a DOBJS+= ${OBJS:.o=.do} -lib${LIB}_debug.a:: ${DOBJS} +lib${LIB}_debug.a:: ${FBSDHDRS} ${DOBJS} @${ECHO} building debug ${LIB} library @rm -f lib${LIB}_debug.a @${AR} cq lib${LIB}_debug.a `lorder ${DOBJS} | tsort -q` ${ARADD} ${RANLIB} lib${LIB}_debug.a -lib${LIB}.a:: ${SOBJS} +lib${LIB}.a:: ${FBSDHDRS} ${SOBJS} @${ECHO} building standard ${LIB} library @rm -f lib${LIB}.a @${AR} cq lib${LIB}.a `lorder ${SOBJS} | tsort -q` ${ARADD} @@ -84,31 +109,42 @@ lib${LIB}.a:: ${SOBJS} CLEANFILES += ${DOBJS} libc_static.a libc_profile.a libc_debug.a -installhdrs: gen_mig_defs - mkdir -p ${DESTDIR}/usr/include/arpa - mkdir -p ${DESTDIR}/usr/include/protocols - mkdir -p ${DESTDIR}/usr/include/mach - mkdir -p ${DESTDIR}/usr/include/objc - mkdir -p ${DESTDIR}/usr/include/servers - ${INSTALL} -c -m 444 ${INSTHDRS} ${DESTDIR}/usr/include - ${INSTALL} -c -m 444 ${ARPA_INSTHDRS} ${DESTDIR}/usr/include/arpa - ${INSTALL} -c -m 444 ${PROTO_INSTHDRS} ${DESTDIR}/usr/include/protocols - ${INSTALL} -c -m 444 ${MACH_INSTHDRS} ${DESTDIR}/usr/include/mach - ${INSTALL} -c -m 444 ${OBJC_INSTHDRS} ${DESTDIR}/usr/include/objc - ${INSTALL} -c -m 444 ${SRVHDRS} ${DESTDIR}/usr/include/servers - mv ${DESTDIR}/usr/include/servers/srvbootstrap.h ${DESTDIR}/usr/include/servers/bootstrap.h - mkdir -p ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/ - mkdir -p ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/architecture - mkdir -p ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/architecture/ppc - mkdir -p ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/btree - mkdir -p ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/machine - mkdir -p ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/objc - install -c -m 444 ${SRCROOT}/db/btree/btree.h ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/btree - install -c -m 444 ${SRCROOT}/db/btree/bt_extern.h ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/btree - install -c -m 444 ${SRCROOT}/ppc/sys/processor_facilities.h ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/architecture/ppc - install -c -m 444 ${SRCROOT}/internat/NXCType.h ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/objc - install -c -m 444 ${SRCROOT}/gen/stack_logging.h ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/ - mv ${DESTDIR}/usr/include/asm.h ${DESTDIR}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/machine +INCDIR = ${DESTDIR}/usr/include +LOCINCDIR = ${DESTDIR}/usr/local/include +SYSTEMFRAMEWORK = ${DESTDIR}/System/Library/Frameworks/System.framework +PRIVHDRS = ${SYSTEMFRAMEWORK}/Versions/B/PrivateHeaders + +installhdrs-md: gen_md_mig_defs + mkdir -p ${INCDIR}/mach/${MACHINE_ARCH} + ${INSTALL} -c -m 444 ${MD_MIGHDRS} ${INCDIR}/mach/${MACHINE_ARCH} + +installhdrs: ${FBSDHDRS} gen_mig_defs + mkdir -p ${INCDIR}/arpa + mkdir -p ${INCDIR}/mach + mkdir -p ${INCDIR}/malloc + mkdir -p ${INCDIR}/objc + mkdir -p ${INCDIR}/protocols + mkdir -p ${INCDIR}/servers + ${INSTALL} -c -m 444 ${INSTHDRS} ${INCDIR} + ${INSTALL} -c -m 444 ${ARPA_INSTHDRS} ${INCDIR}/arpa + ${INSTALL} -c -m 444 ${MACH_INSTHDRS} ${INCDIR}/mach + ${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 + mkdir -p ${LOCINCDIR} + ${INSTALL} -c -m 444 ${LOCALHDRS} ${LOCINCDIR} + mkdir -p ${PRIVHDRS}/architecture/ppc + mkdir -p ${PRIVHDRS}/btree + mkdir -p ${PRIVHDRS}/machine + mkdir -p ${PRIVHDRS}/objc + ${INSTALL} -c -m 444 ${SRCROOT}/ppc/sys/processor_facilities.h ${PRIVHDRS}/architecture/ppc + ${INSTALL} -c -m 444 ${SRCROOT}/db/btree/btree.h ${PRIVHDRS}/btree + ${INSTALL} -c -m 444 ${SRCROOT}/db/btree/bt_extern.h ${PRIVHDRS}/btree + ${INSTALL} -c -m 444 ${SRCROOT}/internat/NXCType.h ${PRIVHDRS}/objc + ${INSTALL} -c -m 444 ${SRCROOT}/gen/stack_logging.h ${PRIVHDRS} + mv ${DESTDIR}/usr/include/asm.h ${PRIVHDRS}/machine + mv ${INCDIR}/servers/srvbootstrap.h ${INCDIR}/servers/bootstrap.h install_lib${LIB}_static.a: ${INSTALL} -c -m 444 lib${LIB}_static.a ${DESTDIR}/usr/local/lib/system/ @@ -119,6 +155,8 @@ install_lib${LIB}_debug.a: install_lib${LIB}.a: ${INSTALL} -c -m 444 lib${LIB}.a ${DESTDIR}/usr/local/lib/system/ +fbsdman: ${FBSDPATCHMAN} + clean: rm -f ${OBJS} ${POBJS} ${DOBJS} ${SOBJS} ${CLEANFILES} rm -f lib${LIB}.a lib${LIB}_static.a lib${LIB}_profile.a \ diff --git a/SYSCALL-LIST b/SYSCALL-LIST index d9b9511..82879f9 100644 --- a/SYSCALL-LIST +++ b/SYSCALL-LIST @@ -22,6 +22,7 @@ dup2 execve _exit fcntl +fhopen flock fork fsync @@ -72,6 +73,7 @@ unmount mprotect msync munmap +nfsclnt nfssvc open pathconf diff --git a/cc-3.3-or-greater b/cc-3.3-or-greater new file mode 100755 index 0000000..edd7937 --- /dev/null +++ b/cc-3.3-or-greater @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +use strict; + +use constant VERSION3_3 => '3.3'; + +sub toint { + my $str = shift; + my $vers = 0; + my @pieces = split(/\./, $str); + for(my $i = 0; $i < 3; $i++) { + $vers = 1000 * $vers + $pieces[$i]; + } + return($vers); +} + +my $info = `cc -v 2>&1`; +my($version) = $info =~ /gcc\s+version\s+(\S+)/; +printf "%s\n", (toint($version) >= toint(VERSION3_3) ? 'YES' : 'NO'); diff --git a/compat-43/FreeBSD/Makefile.inc b/compat-43/FreeBSD/Makefile.inc new file mode 100644 index 0000000..e4abb4d --- /dev/null +++ b/compat-43/FreeBSD/Makefile.inc @@ -0,0 +1,17 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/2/93 +# $FreeBSD: src/lib/libc/compat-43/Makefile.inc,v 1.12 2002/11/18 09:50:54 ru Exp $ + +# compat-43 sources +.PATH: ${.CURDIR}/${MACHINE_ARCH}/compat-43 ${.CURDIR}/compat-43 + +SRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \ + setrgid.c setruid.c sigcompat.c + +MAN+= creat.2 killpg.2 sigpause.2 sigsetmask.2 sigvec.2 +MAN+= gethostid.3 setruid.3 + +MLINKS+=gethostid.3 sethostid.3 +MLINKS+=setruid.3 setrgid.3 + +MLINKS+=sigsetmask.2 sigblock.2 +MLINKS+=sigsetmask.2 sigmask.2 diff --git a/compat-43/creat.2 b/compat-43/FreeBSD/creat.2 similarity index 94% rename from compat-43/creat.2 rename to compat-43/FreeBSD/creat.2 index a6e1828..b62365a 100644 --- a/compat-43/creat.2 +++ b/compat-43/FreeBSD/creat.2 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)creat.2 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/creat.2,v 1.6.2.3 2001/12/14 18:33:49 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/creat.2,v 1.10 2002/12/18 12:45:08 ru Exp $ .\" .Dd June 2, 1993 .Dt CREAT 2 @@ -50,7 +50,9 @@ This interface is made obsolete by: .Ef .Xr open 2 . .Pp -.Fn Creat +The +.Fn creat +function is the same as: .Bd -literal -offset indent open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); @@ -60,5 +62,5 @@ open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); .Sh HISTORY The .Fn creat -function call appeared in +function appeared in .At v6 . diff --git a/compat-43/FreeBSD/creat.c b/compat-43/FreeBSD/creat.c new file mode 100644 index 0000000..7af5b25 --- /dev/null +++ b/compat-43/FreeBSD/creat.c @@ -0,0 +1,50 @@ +/* + * 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" + +int +__creat(const char *path, mode_t mode) +{ + return(_open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); +} +__weak_reference(__creat, creat); +__weak_reference(__creat, _creat); diff --git a/compat-43/gethostid.3 b/compat-43/FreeBSD/gethostid.3 similarity index 95% rename from compat-43/gethostid.3 rename to compat-43/FreeBSD/gethostid.3 index 9ab2e09..4d4b2f6 100644 --- a/compat-43/gethostid.3 +++ b/compat-43/FreeBSD/gethostid.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)gethostid.3 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/gethostid.3,v 1.5.2.5 2001/12/14 18:33:49 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/gethostid.3,v 1.11 2002/12/18 12:45:08 ru Exp $ .\" .Dd June 2, 1993 .Dt GETHOSTID 3 @@ -48,14 +48,18 @@ .Ft void .Fn sethostid "long hostid" .Sh DESCRIPTION -.Fn Sethostid +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. This call is allowed only to the super-user and is normally performed at boot time. .Pp -.Fn Gethostid +The +.Fn gethostid +function returns the 32-bit identifier for the current processor. .Pp This function has been deprecated. diff --git a/compat-43/gethostid.c b/compat-43/FreeBSD/gethostid.c similarity index 64% rename from compat-43/gethostid.c rename to compat-43/FreeBSD/gethostid.c index a0c8d00..0f08fad 100644 --- a/compat-43/gethostid.c +++ b/compat-43/FreeBSD/gethostid.c @@ -1,29 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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 + * 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 @@ -55,16 +31,17 @@ * 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 -#if __STDC__ long gethostid(void) -#else -long -gethostid() -#endif { int mib[2]; size_t size; diff --git a/compat-43/getwd.c b/compat-43/FreeBSD/getwd.c similarity index 62% rename from compat-43/getwd.c rename to compat-43/FreeBSD/getwd.c index 7fd1fba..b15d2e2 100644 --- a/compat-43/getwd.c +++ b/compat-43/FreeBSD/getwd.c @@ -1,29 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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 +/*- + * 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 @@ -55,6 +31,12 @@ * 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 @@ -66,11 +48,9 @@ getwd(buf) char *buf; { char *p; - char buf2[MAXPATHLEN]; - if (p = getcwd(buf2, MAXPATHLEN)) { - (void)strcpy(buf, buf2); - return(buf); - } + + if ( (p = getcwd(buf, MAXPATHLEN)) ) + return(p); (void)strcpy(buf, strerror(errno)); return((char *)NULL); } diff --git a/compat-43/killpg.2 b/compat-43/FreeBSD/killpg.2 similarity index 94% rename from compat-43/killpg.2 rename to compat-43/FreeBSD/killpg.2 index 3e4d963..dc48c22 100644 --- a/compat-43/killpg.2 +++ b/compat-43/FreeBSD/killpg.2 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)killpg.2 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/killpg.2,v 1.6.2.3 2001/12/14 18:33:49 ru Exp $ +.\" $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 @@ -46,7 +46,9 @@ .Ft int .Fn killpg "pid_t pgrp" "int sig" .Sh DESCRIPTION -.Fn Killpg +The +.Fn killpg +function sends the signal .Fa sig to the process group @@ -68,11 +70,15 @@ to any process that is a descendant of the current process. .Sh RETURN VALUES .Rv -std killpg .Sh ERRORS -.Fn Killpg +The +.Fn killpg +function will fail and no signal will be sent if: .Bl -tag -width Er .It Bq Er EINVAL -.Fa Sig +The +.Fa sig +argument is not a valid signal number. .It Bq Er ESRCH No process can be found in the process group specified by @@ -92,5 +98,5 @@ of the sending process. .Sh HISTORY The .Fn killpg -function call appeared in +function appeared in .Bx 4.0 . diff --git a/compat-43/killpg.c b/compat-43/FreeBSD/killpg.c similarity index 62% rename from compat-43/killpg.c rename to compat-43/FreeBSD/killpg.c index e6490bc..a6220f7 100644 --- a/compat-43/killpg.c +++ b/compat-43/FreeBSD/killpg.c @@ -1,29 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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 + * 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 @@ -55,6 +31,12 @@ * 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 @@ -62,13 +44,8 @@ /* * Backwards-compatible killpg(). */ -#if __STDC__ -int killpg(pid_t pgid, int sig) -#else -int killpg(pgid, sig) - pid_t pgid; - int sig; -#endif +int +killpg(pid_t pgid, int sig) { if (pgid == 1) { errno = ESRCH; diff --git a/compat-43/sethostid.c b/compat-43/FreeBSD/sethostid.c similarity index 64% rename from compat-43/sethostid.c rename to compat-43/FreeBSD/sethostid.c index e6fc068..a23ec8e 100644 --- a/compat-43/sethostid.c +++ b/compat-43/FreeBSD/sethostid.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,18 +31,17 @@ * 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 -#if __STDC__ long sethostid(long hostid) -#else -long -sethostid(hostid) - long hostid; -#endif { int mib[2]; diff --git a/compat-43/setpgrp.c b/compat-43/FreeBSD/setpgrp.c similarity index 62% rename from compat-43/setpgrp.c rename to compat-43/FreeBSD/setpgrp.c index e177d97..0c07ce8 100644 --- a/compat-43/setpgrp.c +++ b/compat-43/FreeBSD/setpgrp.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,16 +31,17 @@ * 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 -#if __STDC__ -int setpgrp(pid_t pid, pid_t pgid) -#else -int setpgrp(pid, pgid) - pid_t pid, pgid; -#endif +int +setpgrp(pid_t pid, pid_t pgid) { return(setpgid(pid, pgid)); } diff --git a/locale/localeconv.c b/compat-43/FreeBSD/setrgid.c similarity index 84% rename from locale/localeconv.c rename to compat-43/FreeBSD/setrgid.c index 825f52c..360e562 100644 --- a/locale/localeconv.c +++ b/compat-43/FreeBSD/setrgid.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1991, 1993 + * 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 @@ -32,20 +32,16 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = - "$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.1.1.1.14.1 2001/03/05 10:21:18 obrien Exp $"; +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 +#include -/* - * Return the current locale conversion. - */ -struct lconv * -localeconv() +int +setrgid(gid_t rgid) { - extern struct lconv *__lconv; - return (__lconv); + return (setregid(rgid, -1)); } diff --git a/compat-43/setruid.3 b/compat-43/FreeBSD/setruid.3 similarity index 96% rename from compat-43/setruid.3 rename to compat-43/FreeBSD/setruid.3 index 4ab8b72..ae6900b 100644 --- a/compat-43/setruid.3 +++ b/compat-43/FreeBSD/setruid.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setruid.3 8.1 (Berkeley) 6/2/93 -.\" $FreeBSD: src/lib/libc/compat-43/setruid.3,v 1.5.2.5 2001/12/14 18:33:49 ru Exp $ +.\" $FreeBSD: src/lib/libc/compat-43/setruid.3,v 1.10 2001/10/01 16:08:50 ru Exp $ .\" .Dd June 2, 1993 .Dt SETRUID 3 diff --git a/compat-43/setruid.c b/compat-43/FreeBSD/setruid.c similarity index 63% rename from compat-43/setruid.c rename to compat-43/FreeBSD/setruid.c index 7ab4f9e..5fb6d60 100644 --- a/compat-43/setruid.c +++ b/compat-43/FreeBSD/setruid.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,16 +31,16 @@ * 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 -#ifdef __STDC__ setruid(uid_t ruid) -#else -setruid(ruid) - int ruid; -#endif { return (setreuid(ruid, -1)); diff --git a/compat-43/Makefile.inc b/compat-43/Makefile.inc index 8d6a7e0..33deee3 100644 --- a/compat-43/Makefile.inc +++ b/compat-43/Makefile.inc @@ -4,15 +4,22 @@ # compat-43 sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/compat-43 ${.CURDIR}/compat-43 -SRCS+= creat.c getwd.c send.c setpgrp.c setreuid.c setruid.c \ - gethostid.c killpg.c sethostid.c setregid.c setrgid.c sigcompat.c - +SRCS+= setregid.c setreuid.c sigcompat.c +.include "Makefile.fbsd_begin" +FBSDSRCS= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \ + setrgid.c setruid.c +.include "Makefile.fbsd_end" .if ${LIB} == "c" -MAN2+= creat.2 killpg.2 sigpause.2 sigvec.2 -MAN3+= gethostid.3 setruid.3 +MAN2+= sigblock.2 sigpause.2 sigsetmask.2 sigvec.2 + +.include "Makefile.fbsd_begin" +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 .endif diff --git a/compat-43/sigcompat.c b/compat-43/sigcompat.c index 33c801c..26ae624 100644 --- a/compat-43/sigcompat.c +++ b/compat-43/sigcompat.c @@ -59,6 +59,9 @@ #include #include #include +#if defined(__DYNAMIC__) +extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv); +#endif static int sigvec__(signo, sv, osv, bind) int signo; diff --git a/db/btree/Makefile.inc b/db/btree/Makefile.inc index 9b80605..ffdf5e5 100644 --- a/db/btree/Makefile.inc +++ b/db/btree/Makefile.inc @@ -5,4 +5,4 @@ SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \ bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c \ - bt_utils.c bt_stack.c + bt_utils.c diff --git a/db/btree/bt_close.c b/db/btree/bt_close.c index d203b3a..30afb19 100644 --- a/db/btree/bt_close.c +++ b/db/btree/bt_close.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,12 @@ * 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 +#ifndef __APPLE_ +#endif #include @@ -70,7 +76,7 @@ #include #include "btree.h" -static int bt_meta __P((BTREE *)); +static int bt_meta(BTREE *); /* * BT_CLOSE -- Close a btree. @@ -96,25 +102,30 @@ __bt_close(dbp) t->bt_pinned = NULL; } - /* - * Delete any already deleted record that we've been saving - * because the cursor pointed to it. - */ - if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor)) - return (RET_ERROR); - + /* 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); - if (t->bt_stack) - free(t->bt_stack); - if (t->bt_kbuf) - free(t->bt_kbuf); - if (t->bt_dbuf) - free(t->bt_dbuf); + /* 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); @@ -138,8 +149,6 @@ __bt_sync(dbp, flags) { BTREE *t; int status; - PAGE *h; - void *p; t = dbp->internal; @@ -155,40 +164,15 @@ __bt_sync(dbp, flags) return (RET_ERROR); } - if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED)) + if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED)) return (RET_SUCCESS); - if (ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR) + if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR) return (RET_ERROR); - /* - * Nastiness. If the cursor has been marked for deletion, but not - * actually deleted, we have to make a copy of the page, delete the - * key/data item, sync the file, and then restore the original page - * contents. - */ - if (ISSET(t, B_DELCRSR)) { - if ((p = (void *)malloc(t->bt_psize)) == NULL) - return (RET_ERROR); - if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) - return (RET_ERROR); - memmove(p, h, t->bt_psize); - if ((status = - __bt_dleaf(t, h, t->bt_bcursor.index)) == RET_ERROR) - goto ecrsr; - mpool_put(t->bt_mp, h, MPOOL_DIRTY); - } - if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS) - CLR(t, B_MODIFIED); - -ecrsr: if (ISSET(t, B_DELCRSR)) { - if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) - return (RET_ERROR); - memmove(h, p, t->bt_psize); - free(p); - mpool_put(t->bt_mp, h, MPOOL_DIRTY); - } + F_CLR(t, B_MODIFIED); + return (status); } @@ -212,12 +196,12 @@ bt_meta(t) return (RET_ERROR); /* Fill in metadata. */ - m.m_magic = BTREEMAGIC; - m.m_version = BTREEVERSION; - m.m_psize = t->bt_psize; - m.m_free = t->bt_free; - m.m_nrecs = t->bt_nrecs; - m.m_flags = t->bt_flags & SAVEMETA; + 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); diff --git a/db/btree/bt_conv.c b/db/btree/bt_conv.c index 67c1817..c81650e 100644 --- a/db/btree/bt_conv.c +++ b/db/btree/bt_conv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -66,7 +70,7 @@ #include #include "btree.h" -static void mswap __P((PAGE *)); +static void mswap(PAGE *); /* * __BT_BPGIN, __BT_BPGOUT -- @@ -89,7 +93,7 @@ __bt_pgin(t, pg, pp) u_char flags; char *p; - if (!ISSET(((BTREE *)t), B_NEEDSWAP)) + if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) return; if (pg == P_META) { mswap(pp); @@ -110,7 +114,7 @@ __bt_pgin(t, pg, pp) M_16_SWAP(h->linp[i]); p = (char *)GETBINTERNAL(h, i); P_32_SWAP(p); - p += sizeof(size_t); + p += sizeof(u_int32_t); P_32_SWAP(p); p += sizeof(pgno_t); if (*(u_char *)p & P_BIGKEY) { @@ -125,9 +129,9 @@ __bt_pgin(t, pg, pp) M_16_SWAP(h->linp[i]); p = (char *)GETBLEAF(h, i); P_32_SWAP(p); - p += sizeof(size_t); + p += sizeof(u_int32_t); P_32_SWAP(p); - p += sizeof(size_t); + p += sizeof(u_int32_t); flags = *(u_char *)p; if (flags & (P_BIGKEY | P_BIGDATA)) { p += sizeof(u_char); @@ -137,7 +141,7 @@ __bt_pgin(t, pg, pp) P_32_SWAP(p); } if (flags & P_BIGDATA) { - p += sizeof(size_t); + p += sizeof(u_int32_t); P_32_SWAP(p); p += sizeof(pgno_t); P_32_SWAP(p); @@ -157,7 +161,7 @@ __bt_pgout(t, pg, pp) u_char flags; char *p; - if (!ISSET(((BTREE *)t), B_NEEDSWAP)) + if (!F_ISSET(((BTREE *)t), B_NEEDSWAP)) return; if (pg == P_META) { mswap(pp); @@ -170,7 +174,7 @@ __bt_pgout(t, pg, pp) for (i = 0; i < top; i++) { p = (char *)GETBINTERNAL(h, i); P_32_SWAP(p); - p += sizeof(size_t); + p += sizeof(u_int32_t); P_32_SWAP(p); p += sizeof(pgno_t); if (*(u_char *)p & P_BIGKEY) { @@ -185,9 +189,9 @@ __bt_pgout(t, pg, pp) for (i = 0; i < top; i++) { p = (char *)GETBLEAF(h, i); P_32_SWAP(p); - p += sizeof(size_t); + p += sizeof(u_int32_t); P_32_SWAP(p); - p += sizeof(size_t); + p += sizeof(u_int32_t); flags = *(u_char *)p; if (flags & (P_BIGKEY | P_BIGDATA)) { p += sizeof(u_char); @@ -197,7 +201,7 @@ __bt_pgout(t, pg, pp) P_32_SWAP(p); } if (flags & P_BIGDATA) { - p += sizeof(size_t); + p += sizeof(u_int32_t); P_32_SWAP(p); p += sizeof(pgno_t); P_32_SWAP(p); @@ -227,16 +231,16 @@ mswap(pg) char *p; p = (char *)pg; - P_32_SWAP(p); /* m_magic */ + P_32_SWAP(p); /* magic */ p += sizeof(u_int32_t); - P_32_SWAP(p); /* m_version */ + P_32_SWAP(p); /* version */ p += sizeof(u_int32_t); - P_32_SWAP(p); /* m_psize */ + P_32_SWAP(p); /* psize */ p += sizeof(u_int32_t); - P_32_SWAP(p); /* m_free */ + P_32_SWAP(p); /* free */ p += sizeof(u_int32_t); - P_32_SWAP(p); /* m_nrecs */ + P_32_SWAP(p); /* nrecs */ p += sizeof(u_int32_t); - P_32_SWAP(p); /* m_flags */ + P_32_SWAP(p); /* flags */ p += sizeof(u_int32_t); } diff --git a/db/btree/bt_debug.c b/db/btree/bt_debug.c index 490d345..ffef39e 100644 --- a/db/btree/bt_debug.c +++ b/db/btree/bt_debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -86,24 +90,22 @@ __bt_dump(dbp) t = dbp->internal; (void)fprintf(stderr, "%s: pgsz %d", - ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); - if (ISSET(t, R_RECNO)) + F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); + if (F_ISSET(t, R_RECNO)) (void)fprintf(stderr, " keys %lu", t->bt_nrecs); #undef X #define X(flag, name) \ - if (ISSET(t, flag)) { \ + if (F_ISSET(t, flag)) { \ (void)fprintf(stderr, "%s%s", sep, name); \ sep = ", "; \ } - if (t->bt_flags) { + if (t->flags != 0) { sep = " flags ("; - X(B_DELCRSR, "DELCRSR"); X(R_FIXLEN, "FIXLEN"); X(B_INMEM, "INMEM"); X(B_NODUPS, "NODUPS"); X(B_RDONLY, "RDONLY"); X(R_RECNO, "RECNO"); - X(B_SEQINIT, "SEQINIT"); X(B_METADIRTY,"METADIRTY"); (void)fprintf(stderr, ")\n"); } @@ -129,19 +131,19 @@ __bt_dmpage(h) char *sep; m = (BTMETA *)h; - (void)fprintf(stderr, "magic %lx\n", m->m_magic); - (void)fprintf(stderr, "version %lu\n", m->m_version); - (void)fprintf(stderr, "psize %lu\n", m->m_psize); - (void)fprintf(stderr, "free %lu\n", m->m_free); - (void)fprintf(stderr, "nrecs %lu\n", m->m_nrecs); - (void)fprintf(stderr, "flags %lu", m->m_flags); + (void)fprintf(stderr, "magic %lx\n", m->magic); + (void)fprintf(stderr, "version %lu\n", m->version); + (void)fprintf(stderr, "psize %lu\n", m->psize); + (void)fprintf(stderr, "free %lu\n", m->free); + (void)fprintf(stderr, "nrecs %lu\n", m->nrecs); + (void)fprintf(stderr, "flags %lu", m->flags); #undef X #define X(flag, name) \ - if (m->m_flags & flag) { \ + if (m->flags & flag) { \ (void)fprintf(stderr, "%s%s", sep, name); \ sep = ", "; \ } - if (m->m_flags) { + if (m->flags) { sep = " ("; X(B_NODUPS, "NODUPS"); X(R_RECNO, "RECNO"); @@ -213,7 +215,7 @@ __bt_dpage(h) 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) { + switch (h->flags & P_TYPE) { case P_BINTERNAL: bi = GETBINTERNAL(h, cur); (void)fprintf(stderr, @@ -235,14 +237,14 @@ __bt_dpage(h) (void)fprintf(stderr, "big key page %lu size %u/", *(pgno_t *)bl->bytes, - *(size_t *)(bl->bytes + sizeof(pgno_t))); + *(u_int32_t *)(bl->bytes + sizeof(pgno_t))); else if (bl->ksize) (void)fprintf(stderr, "%s/", bl->bytes); if (bl->flags & P_BIGDATA) (void)fprintf(stderr, "big data page %lu size %u", *(pgno_t *)(bl->bytes + bl->ksize), - *(size_t *)(bl->bytes + bl->ksize + + *(u_int32_t *)(bl->bytes + bl->ksize + sizeof(pgno_t))); else if (bl->dsize) (void)fprintf(stderr, "%.*s", @@ -254,7 +256,7 @@ __bt_dpage(h) (void)fprintf(stderr, "big data page %lu size %u", *(pgno_t *)rl->bytes, - *(size_t *)(rl->bytes + sizeof(pgno_t))); + *(u_int32_t *)(rl->bytes + sizeof(pgno_t))); else if (rl->dsize) (void)fprintf(stderr, "%.*s", (int)rl->dsize, rl->bytes); @@ -288,7 +290,7 @@ __bt_stat(dbp) 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) { + switch (h->flags & P_TYPE) { case P_BINTERNAL: case P_RINTERNAL: ++pinternal; @@ -316,7 +318,7 @@ __bt_stat(dbp) (void)mpool_put(t->bt_mp, h, 0); break; } - i = ISSET(t, R_RECNO) ? + i = F_ISSET(t, R_RECNO) ? GETRINTERNAL(h, 0)->pgno : GETBINTERNAL(h, 0)->pgno; (void)mpool_put(t->bt_mp, h, 0); @@ -324,7 +326,7 @@ __bt_stat(dbp) (void)fprintf(stderr, "%d level%s with %ld keys", levels, levels == 1 ? "" : "s", nkeys); - if (ISSET(t, R_RECNO)) + if (F_ISSET(t, R_RECNO)) (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs); (void)fprintf(stderr, "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n", diff --git a/db/btree/bt_delete.c b/db/btree/bt_delete.c index f8ace92..79791ec 100644 --- a/db/btree/bt_delete.c +++ b/db/btree/bt_delete.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -68,18 +72,17 @@ #include #include "btree.h" -static int bt_bdelete __P((BTREE *, const DBT *)); +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. - * - * Parameters: - * dbp: pointer to access method - * key: key to delete - * flags: R_CURSOR if deleting what the cursor references + * __bt_delete + * Delete the item(s) referenced by a key. * - * Returns: - * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. + * Return RET_SPECIAL if the key is not found. */ int __bt_delete(dbp, key, flags) @@ -88,6 +91,8 @@ __bt_delete(dbp, key, flags) u_int flags; { BTREE *t; + CURSOR *c; + PAGE *h; int status; t = dbp->internal; @@ -98,242 +103,433 @@ __bt_delete(dbp, key, flags) t->bt_pinned = NULL; } - if (ISSET(t, B_RDONLY)) { + /* Check for change to a read-only tree. */ + if (F_ISSET(t, B_RDONLY)) { errno = EPERM; return (RET_ERROR); } - switch(flags) { + switch (flags) { case 0: - status = bt_bdelete(t, key); + 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 the record. For - * the delete cursor bit to have been set requires that the - * scan be initialized, so no reason to check. + * If flags is R_CURSOR, delete the cursor. Must already + * have started a scan and not have already deleted it. */ - if (!ISSET(t, B_SEQINIT)) - goto einval; - status = ISSET(t, B_DELCRSR) ? - RET_SPECIAL : __bt_crsrdel(t, &t->bt_bcursor); - break; + 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: -einval: errno = EINVAL; + errno = EINVAL; return (RET_ERROR); } if (status == RET_SUCCESS) - SET(t, B_MODIFIED); + F_SET(t, B_MODIFIED); return (status); } /* - * BT_BDELETE -- Delete all key/data pairs matching the specified key. + * __bt_stkacq -- + * Acquire a stack so we can delete a cursor entry. * * Parameters: - * tree: tree + * 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) +__bt_bdelete(t, key) BTREE *t; const DBT *key; { - EPG *e, save; + EPG *e; PAGE *h; - pgno_t cpgno, pg; - indx_t cindex; - int deleted, dirty1, dirty2, exact; + int deleted, exact, redo; + + deleted = 0; /* Find any matching record; __bt_search pins the page. */ - if ((e = __bt_search(t, key, &exact)) == NULL) - return (RET_ERROR); +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 (RET_SPECIAL); + return (deleted ? RET_SUCCESS : RET_SPECIAL); } /* - * Delete forward, then delete backward, from the found key. The - * ordering is so that the deletions don't mess up the page refs. - * The first loop deletes the key from the original page, the second - * unpins the original page. In the first loop, dirty1 is set if - * the original page is modified, and dirty2 is set if any subsequent - * pages are modified. In the second loop, dirty1 starts off set if - * the original page has been modified, and is set if any subsequent - * pages are modified. - * - * If find the key referenced by the cursor, don't delete it, just - * flag it for future deletion. The cursor page number is P_INVALID - * unless the sequential scan is initialized, so no reason to check. - * A special case is when the already deleted cursor record was the - * only record found. If so, then the delete opertion fails as no - * records were deleted. - * - * Cycle in place in the current page until the current record doesn't - * match the key or the page is empty. If the latter, walk forward, - * skipping empty pages and repeating until a record doesn't match - * the key or the end of the tree is reached. + * 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. */ - cpgno = t->bt_bcursor.pgno; - cindex = t->bt_bcursor.index; - save = *e; - dirty1 = 0; - for (h = e->page, deleted = 0;;) { - dirty2 = 0; - do { - if (h->pgno == cpgno && e->index == cindex) { - if (!ISSET(t, B_DELCRSR)) { - SET(t, B_DELCRSR); - deleted = 1; - } - ++e->index; - } else { - if (__bt_dleaf(t, h, e->index)) { - if (h->pgno != save.page->pgno) - mpool_put(t->bt_mp, h, dirty2); - mpool_put(t->bt_mp, save.page, dirty1); + 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); - } - if (h->pgno == save.page->pgno) - dirty1 = MPOOL_DIRTY; - else - dirty2 = MPOOL_DIRTY; - deleted = 1; - } - } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0); - - /* - * Quit if didn't find a match, no next page, or first key on - * the next page doesn't match. Don't unpin the original page - * unless an error occurs. - */ - if (e->index < NEXTINDEX(h)) - break; - for (;;) { - if ((pg = h->nextpg) == P_INVALID) - goto done1; - if (h->pgno != save.page->pgno) - mpool_put(t->bt_mp, h, dirty2); - if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) { - mpool_put(t->bt_mp, save.page, dirty1); - return (RET_ERROR); - } - if (NEXTINDEX(h) != 0) { - e->page = h; - e->index = 0; - break; - } + } 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; } - /* - * Reach here with the original page and the last page referenced - * pinned (they may be the same). Release it if not the original. - */ -done1: if (h->pgno != save.page->pgno) - mpool_put(t->bt_mp, h, dirty2); + /* 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 backwards from the record previous to the record returned by - * __bt_search, skipping empty pages, until a record doesn't match - * the key or reach the beginning of the tree. + * 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. */ - *e = save; - for (;;) { - if (e->index) - --e->index; - for (h = e->page; e->index; --e->index) { - if (__bt_cmp(t, key, e) != 0) - goto done2; - if (h->pgno == cpgno && e->index == cindex) { - if (!ISSET(t, B_DELCRSR)) { - SET(t, B_DELCRSR); - deleted = 1; - } + 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_dleaf(t, h, e->index) == RET_ERROR) { - mpool_put(t->bt_mp, h, dirty1); + if (__bt_relink(t, pg) || __bt_free(t, pg)) return (RET_ERROR); - } - if (h->pgno == save.page->pgno) - dirty1 = MPOOL_DIRTY; - deleted = 1; + 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); } - if ((pg = h->prevpg) == P_INVALID) - goto done2; - mpool_put(t->bt_mp, h, dirty1); - dirty1 = 0; - if ((e->page = mpool_get(t->bt_mp, pg, 0)) == NULL) - return (RET_ERROR); - e->index = NEXTINDEX(e->page); + mpool_put(t->bt_mp, pg, MPOOL_DIRTY); + break; } - /* - * Reach here with the last page that was looked at pinned. Release - * it. - */ -done2: mpool_put(t->bt_mp, h, dirty1); - return (deleted ? RET_SUCCESS : RET_SPECIAL); + /* 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. + * __bt_dleaf -- + * Delete a single record from a leaf page. * * Parameters: * t: tree - * index: index on current page to delete + * key: referenced key + * h: page + * index: index on page to delete * * Returns: * RET_SUCCESS, RET_ERROR. */ int -__bt_dleaf(t, h, index) +__bt_dleaf(t, key, h, index) BTREE *t; + const DBT *key; PAGE *h; - indx_t index; + u_int index; { - register BLEAF *bl; - register indx_t cnt, *ip, offset; - register size_t nbytes; - char *from; + BLEAF *bl; + indx_t cnt, *ip, offset; + u_int32_t nbytes; void *to; + char *from; - /* - * Delete a record from a btree 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. - */ + /* 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); - nbytes = NBLEAF(bl); - /* - * Compress the key/data pairs. Compress and adjust the [BR]LEAF - * offsets. Reset the headers. - */ + /* 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) @@ -341,5 +537,146 @@ __bt_dleaf(t, h, index) 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_get.c b/db/btree/bt_get.c index b44ed5a..09479a7 100644 --- a/db/btree/bt_get.c +++ b/db/btree/bt_get.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -112,148 +116,15 @@ __bt_get(dbp, key, data, flags) return (RET_SPECIAL); } - /* - * A special case is if we found the record but it's flagged for - * deletion. In this case, we want to find another record with the - * same key, if it exists. Rather than look around the tree we call - * __bt_first and have it redo the search, as __bt_first will not - * return keys marked for deletion. Slow, but should never happen. - */ - if (ISSET(t, B_DELCRSR) && e->page->pgno == t->bt_bcursor.pgno && - e->index == t->bt_bcursor.index) { - mpool_put(t->bt_mp, e->page, 0); - if ((e = __bt_first(t, key, &exact)) == NULL) - return (RET_ERROR); - if (!exact) - return (RET_SPECIAL); - } + status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0); - status = __bt_ret(t, e, NULL, data); /* * If the user is doing concurrent access, we copied the * key/data, toss the page. */ - if (ISSET(t, B_DB_LOCK)) + if (F_ISSET(t, B_DB_LOCK)) mpool_put(t->bt_mp, e->page, 0); else t->bt_pinned = e->page; return (status); } - -/* - * __BT_FIRST -- Find the first entry. - * - * Parameters: - * t: the tree - * key: the key - * - * Returns: - * The first entry in the tree greater than or equal to key. - */ -EPG * -__bt_first(t, key, exactp) - BTREE *t; - const DBT *key; - int *exactp; -{ - register PAGE *h; - register EPG *e; - EPG save; - pgno_t cpgno, pg; - indx_t cindex; - int found; - - /* - * Find any matching record; __bt_search pins the page. Only exact - * matches are tricky, otherwise just return the location of the key - * if it were to be inserted into the tree. - */ - if ((e = __bt_search(t, key, exactp)) == NULL) - return (NULL); - if (!*exactp) - return (e); - - if (ISSET(t, B_DELCRSR)) { - cpgno = t->bt_bcursor.pgno; - cindex = t->bt_bcursor.index; - } else { - cpgno = P_INVALID; - cindex = 0; /* GCC thinks it's uninitialized. */ - } - - /* - * Walk backwards, skipping empty pages, 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. A special case is that we don't return a match - * on records that the cursor references that have already been flagged - * for deletion. - */ - save = *e; - h = e->page; - found = 0; - do { - if (cpgno != h->pgno || cindex != e->index) { - if (save.page->pgno != e->page->pgno) { - mpool_put(t->bt_mp, save.page, 0); - save = *e; - } else - save.index = e->index; - found = 1; - } - /* - * Make a special effort not to unpin the page the last (or - * original) match was on, but also make sure it's unpinned - * if an error occurs. - */ - while (e->index == 0) { - if (h->prevpg == P_INVALID) - goto done1; - 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 (NULL); - } - e->page = h; - e->index = NEXTINDEX(h); - } - --e->index; - } while (__bt_cmp(t, key, e) == 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. - */ -done1: if (h->pgno != save.page->pgno) - mpool_put(t->bt_mp, h, 0); - - /* - * If still haven't found a record, the only possibility left is the - * next one. Move forward one slot, skipping empty pages and check. - */ - if (!found) { - h = save.page; - if (++save.index == NEXTINDEX(h)) { - do { - pg = h->nextpg; - mpool_put(t->bt_mp, h, 0); - if (pg == P_INVALID) { - *exactp = 0; - return (e); - } - if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) - return (NULL); - } while ((save.index = NEXTINDEX(h)) == 0); - save.page = h; - } - if (__bt_cmp(t, key, &save) != 0) { - *exactp = 0; - return (e); - } - } - *e = save; - *exactp = 1; - return (e); -} diff --git a/db/btree/bt_open.c b/db/btree/bt_open.c index 6ceba3e..71fd3bb 100644 --- a/db/btree/bt_open.c +++ b/db/btree/bt_open.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 /* * Implementation of btree access method for 4.4BSD. @@ -82,9 +86,14 @@ #include #include "btree.h" -static int byteorder __P((void)); -static int nroot __P((BTREE *)); -static int tmp __P((void)); +#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. @@ -141,7 +150,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) */ if (b.psize && (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 || - b.psize & sizeof(indx_t) - 1)) + b.psize & (sizeof(indx_t) - 1) )) goto einval; /* Minimum number of keys per page; absolute minimum is 2. */ @@ -178,7 +187,6 @@ __bt_open(fname, flags, mode, openinfo, dflags) if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL) goto err; memset(t, 0, sizeof(BTREE)); - t->bt_bcursor.pgno = P_INVALID; t->bt_fd = -1; /* Don't close unopened fd on error. */ t->bt_lorder = b.lorder; t->bt_order = NOT; @@ -188,9 +196,9 @@ __bt_open(fname, flags, mode, openinfo, dflags) if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL) goto err; - t->bt_flags = 0; + memset(t->bt_dbp, 0, sizeof(DB)); if (t->bt_lorder != machine_lorder) - SET(t, B_NEEDSWAP); + F_SET(t, B_NEEDSWAP); dbp->type = DB_BTREE; dbp->internal = t; @@ -207,9 +215,9 @@ __bt_open(fname, flags, mode, openinfo, dflags) * open a backing temporary file. Otherwise, it's a disk-based tree. */ if (fname) { - switch(flags & O_ACCMODE) { + switch (flags & O_ACCMODE) { case O_RDONLY: - SET(t, B_RDONLY); + F_SET(t, B_RDONLY); break; case O_RDWR: break; @@ -226,7 +234,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) goto einval; if ((t->bt_fd = tmp()) == -1) goto err; - SET(t, B_INMEM); + F_SET(t, B_INMEM); } if (fcntl(t->bt_fd, F_SETFD, 1) == -1) @@ -235,8 +243,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) if (fstat(t->bt_fd, &sb)) goto err; if (sb.st_size) { - nr = read(t->bt_fd, &m, sizeof(BTMETA)); - if (nr < 0) + if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0) goto err; if (nr != sizeof(BTMETA)) goto eftype; @@ -249,28 +256,28 @@ __bt_open(fname, flags, mode, openinfo, dflags) * don't bother to return an error, we just clear the NEEDSWAP * bit. */ - if (m.m_magic == BTREEMAGIC) - CLR(t, B_NEEDSWAP); + if (m.magic == BTREEMAGIC) + F_CLR(t, B_NEEDSWAP); else { - SET(t, B_NEEDSWAP); - M_32_SWAP(m.m_magic); - M_32_SWAP(m.m_version); - M_32_SWAP(m.m_psize); - M_32_SWAP(m.m_free); - M_32_SWAP(m.m_nrecs); - M_32_SWAP(m.m_flags); + 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.m_magic != BTREEMAGIC || m.m_version != BTREEVERSION) + if (m.magic != BTREEMAGIC || m.version != BTREEVERSION) goto eftype; - if (m.m_psize < MINPSIZE || m.m_psize > MAX_PAGE_OFFSET + 1 || - m.m_psize & sizeof(indx_t) - 1) + if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 || + m.psize & (sizeof(indx_t) - 1) ) goto eftype; - if (m.m_flags & ~SAVEMETA) + if (m.flags & ~SAVEMETA) goto eftype; - b.psize = m.m_psize; - t->bt_flags |= m.m_flags; - t->bt_free = m.m_free; - t->bt_nrecs = m.m_nrecs; + 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. @@ -286,18 +293,18 @@ __bt_open(fname, flags, mode, openinfo, dflags) /* Set flag if duplicates permitted. */ if (!(b.flags & R_DUP)) - SET(t, B_NODUPS); + F_SET(t, B_NODUPS); t->bt_free = P_INVALID; t->bt_nrecs = 0; - SET(t, B_METADIRTY); + 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.cachesize & (b.psize - 1) ) + b.cachesize += (~b.cachesize & (b.psize - 1) ) + 1; if (b.cachesize < b.psize * MINCACHE) b.cachesize = b.psize * MINCACHE; @@ -325,7 +332,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) if ((t->bt_mp = mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL) goto err; - if (!ISSET(t, B_INMEM)) + if (!F_ISSET(t, B_INMEM)) mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t); /* Create a root page if new tree. */ @@ -334,11 +341,11 @@ __bt_open(fname, flags, mode, openinfo, dflags) /* Global flags. */ if (dflags & DB_LOCK) - SET(t, B_DB_LOCK); + F_SET(t, B_DB_LOCK); if (dflags & DB_SHMEM) - SET(t, B_DB_SHMEM); + F_SET(t, B_DB_SHMEM); if (dflags & DB_TXN) - SET(t, B_DB_TXN); + F_SET(t, B_DB_TXN); return (dbp); @@ -378,8 +385,9 @@ nroot(t) mpool_put(t->bt_mp, meta, 0); return (RET_SUCCESS); } - if (errno != EINVAL) + 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); @@ -405,12 +413,13 @@ tmp() { sigset_t set, oset; int fd; - char *envtmp; + char *envtmp = NULL; char path[MAXPATHLEN]; - envtmp = getenv("TMPDIR"); + if (issetugid() == 0) + envtmp = getenv("TMPDIR"); (void)snprintf(path, - sizeof(path), "%s/bt.XXXXXX", envtmp ? envtmp : "/tmp"); + sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp"); (void)sigfillset(&set); (void)sigprocmask(SIG_BLOCK, &set, &oset); @@ -453,7 +462,7 @@ __bt_fd(dbp) } /* In-memory database can't have a file descriptor. */ - if (ISSET(t, B_INMEM)) { + if (F_ISSET(t, B_INMEM)) { errno = ENOENT; return (-1); } diff --git a/db/btree/bt_overflow.c b/db/btree/bt_overflow.c index 7a92814..489290e 100644 --- a/db/btree/bt_overflow.c +++ b/db/btree/bt_overflow.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -90,7 +94,7 @@ * * Parameters: * t: tree - * p: pointer to { pgno_t, size_t } + * p: pointer to { pgno_t, u_int32_t } * buf: storage address * bufsz: storage size * @@ -102,15 +106,16 @@ __ovfl_get(t, p, ssz, buf, bufsz) BTREE *t; void *p; size_t *ssz; - char **buf; + void **buf; size_t *bufsz; { PAGE *h; pgno_t pg; - size_t nb, plen, sz; + size_t nb, plen; + u_int32_t sz; memmove(&pg, p, sizeof(pgno_t)); - memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(size_t)); + memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t)); *ssz = sz; #ifdef DEBUG @@ -119,7 +124,8 @@ __ovfl_get(t, p, ssz, buf, bufsz) #endif /* Make the buffer bigger as necessary. */ if (*bufsz < sz) { - if ((*buf = (char *)realloc(*buf, sz)) == NULL) + *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz)); + if (*buf == NULL) return (RET_ERROR); *bufsz = sz; } @@ -163,7 +169,8 @@ __ovfl_put(t, dbt, pg) PAGE *h, *last; void *p; pgno_t npg; - size_t nb, plen, sz; + size_t nb, plen; + u_int32_t sz; /* * Allocate pages and copy the key/data record into them. Store the @@ -202,7 +209,7 @@ __ovfl_put(t, dbt, pg) * * Parameters: * t: tree - * p: pointer to { pgno_t, size_t } + * p: pointer to { pgno_t, u_int32_t } * * Returns: * RET_ERROR, RET_SUCCESS @@ -214,10 +221,11 @@ __ovfl_delete(t, p) { PAGE *h; pgno_t pg; - size_t plen, sz; + size_t plen; + u_int32_t sz; memmove(&pg, p, sizeof(pgno_t)); - memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(size_t)); + memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t)); #ifdef DEBUG if (pg == P_INVALID || sz == 0) diff --git a/db/btree/bt_page.c b/db/btree/bt_page.c index 7b483f9..b476b49 100644 --- a/db/btree/bt_page.c +++ b/db/btree/bt_page.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -55,6 +55,10 @@ * 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 #include @@ -64,7 +68,8 @@ #include "btree.h" /* - * __BT_FREE -- Put a page on the freelist. + * __bt_free -- + * Put a page on the freelist. * * Parameters: * t: tree @@ -72,23 +77,28 @@ * * 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 start of the free list. */ + /* 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. + * __bt_new -- + * Get a new page, preferably from the freelist. * * Parameters: * t: tree @@ -106,9 +116,10 @@ __bt_new(t, npg) 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; - return (h); + *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.c b/db/btree/bt_put.c index c7f61c7..41d43c5 100644 --- a/db/btree/bt_put.c +++ b/db/btree/bt_put.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -69,7 +73,7 @@ #include #include "btree.h" -static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *)); +static EPG *bt_fast(BTREE *, const DBT *, const DBT *, int *); /* * __BT_PUT -- Add a btree item to the tree. @@ -97,7 +101,7 @@ __bt_put(dbp, key, data, flags) PAGE *h; indx_t index, nxtindex; pgno_t pg; - size_t nbytes; + u_int32_t nbytes; int dflags, exact, status; char *dest, db[NOVFLSIZE], kb[NOVFLSIZE]; @@ -109,33 +113,38 @@ __bt_put(dbp, key, data, flags) 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 R_CURSOR: - if (!ISSET(t, B_SEQINIT)) - goto einval; - if (ISSET(t, B_DELCRSR)) - goto einval; - break; 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: -einval: errno = EINVAL; - return (RET_ERROR); - } - - if (ISSET(t, B_RDONLY)) { - errno = EPERM; + errno = EINVAL; return (RET_ERROR); } /* - * If the key/data won't fit on a page, store it on indirect pages. - * Only store the key on the overflow page if it's too big after the - * data is on an overflow page. + * 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, these pages aren't recovered. + * If the insert fails later on, the overflow pages aren't recovered. */ dflags = 0; if (key->size + data->size > t->bt_ovflsize) { @@ -146,7 +155,7 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) tkey.size = NOVFLSIZE; memmove(kb, &pg, sizeof(pgno_t)); memmove(kb + sizeof(pgno_t), - &key->size, sizeof(size_t)); + &key->size, sizeof(u_int32_t)); dflags |= P_BIGKEY; key = &tkey; } @@ -157,7 +166,7 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) tdata.size = NOVFLSIZE; memmove(db, &pg, sizeof(pgno_t)); memmove(db + sizeof(pgno_t), - &data->size, sizeof(size_t)); + &data->size, sizeof(u_int32_t)); dflags |= P_BIGDATA; data = &tdata; } @@ -167,15 +176,15 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) /* Replace the cursor. */ if (flags == R_CURSOR) { - if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) + if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL) return (RET_ERROR); - index = t->bt_bcursor.index; + 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 pin the returned page. + * 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) @@ -184,34 +193,26 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR) index = e->index; /* - * Add the specified 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. - * - * Pages are split as required. + * 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; - /* - * One special case is if the cursor references the record and - * it's been flagged for deletion. Then, we delete the record, - * leaving the cursor there -- this means that the inserted - * record will not be seen in a cursor scan. - */ - if (ISSET(t, B_DELCRSR) && t->bt_bcursor.pgno == h->pgno && - t->bt_bcursor.index == index) { - CLR(t, B_DELCRSR); - goto delete; - } mpool_put(t->bt_mp, h, 0); return (RET_SPECIAL); default: - if (!exact || !ISSET(t, B_NODUPS)) + if (!exact || !F_ISSET(t, B_NODUPS)) break; -delete: if (__bt_dleaf(t, h, index) == RET_ERROR) { + /* + * !!! + * Note, the delete may empty the page, so we need to put a + * new entry into the page immediately. + */ +delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) { mpool_put(t->bt_mp, h, 0); return (RET_ERROR); } @@ -241,7 +242,13 @@ delete: if (__bt_dleaf(t, h, index) == RET_ERROR) { dest = (char *)h + h->upper; WR_BLEAF(dest, key, data, dflags); - if (t->bt_order == NOT) + /* 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; @@ -255,15 +262,15 @@ delete: if (__bt_dleaf(t, h, index) == RET_ERROR) { t->bt_last.pgno = h->pgno; } } + } mpool_put(t->bt_mp, h, MPOOL_DIRTY); success: - if (flags == R_SETCURSOR) { - t->bt_bcursor.pgno = e->page->pgno; - t->bt_bcursor.index = e->index; - } - SET(t, B_MODIFIED); + if (flags == R_SETCURSOR) + __bt_setcur(t, e->page->pgno, e->index); + + F_SET(t, B_MODIFIED); return (RET_SUCCESS); } @@ -288,7 +295,7 @@ bt_fast(t, key, data, exactp) int *exactp; { PAGE *h; - size_t nbytes; + u_int32_t nbytes; int cmp; if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) { @@ -299,8 +306,8 @@ bt_fast(t, key, data, exactp) 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. + * 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)) diff --git a/db/btree/bt_search.c b/db/btree/bt_search.c index 67a0f6c..f929661 100644 --- a/db/btree/bt_search.c +++ b/db/btree/bt_search.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -66,11 +70,12 @@ #include #include "btree.h" -static int bt_snext __P((BTREE *, PAGE *, const DBT *, int *)); -static int bt_sprev __P((BTREE *, PAGE *, const DBT *, int *)); +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. + * __bt_search -- + * Search a btree for a key. * * Parameters: * t: tree to search @@ -116,24 +121,26 @@ __bt_search(t, key, exactp) } /* - * If it's a leaf page, and duplicates aren't allowed, we're - * done. If duplicates are allowed, it's possible that there - * were duplicate keys on duplicate pages, and they were later - * deleted, so we could be on a page with no matches while - * there are matches on other pages. If we're at the start or - * end of a page, check on both sides. + * 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) { - t->bt_cur.index = base; - *exactp = 0; - if (!ISSET(t, B_NODUPS)) { + if (!F_ISSET(t, B_NODUPS)) { if (base == 0 && - bt_sprev(t, h, key, exactp)) + h->prevpg != P_INVALID && + __bt_sprev(t, h, key, exactp)) return (&t->bt_cur); if (base == NEXTINDEX(h) && - bt_snext(t, h, key, exactp)) + 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); } @@ -146,111 +153,86 @@ __bt_search(t, key, exactp) */ index = base ? base - 1 : base; -next: if (__bt_push(t, h->pgno, index) == RET_ERROR) - return (NULL); +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. + * __bt_snext -- + * Check for an exact match after the key. * * Parameters: - * t: tree to search - * h: current page. - * key: key to find + * 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) +__bt_snext(t, h, key, exactp) BTREE *t; PAGE *h; const DBT *key; int *exactp; { EPG e; - PAGE *tp; - pgno_t pg; - /* Skip until reach the end of the tree or a key. */ - for (pg = h->nextpg; pg != P_INVALID;) { - if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) { - mpool_put(t->bt_mp, h, 0); - return (NULL); - } - if (NEXTINDEX(tp) != 0) - break; - pg = tp->prevpg; - mpool_put(t->bt_mp, tp, 0); - } /* - * The key is either an exact match, or not as good as - * the one we already have. + * Get the next page. The key is either an exact + * match, or not as good as the one we already have. */ - if (pg != P_INVALID) { - e.page = tp; - e.index = NEXTINDEX(tp) - 1; - if (__bt_cmp(t, key, &e) == 0) { - mpool_put(t->bt_mp, h, 0); - t->bt_cur = e; - *exactp = 1; - return (1); - } + 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. + * __bt_sprev -- + * Check for an exact match before the key. * * Parameters: - * t: tree to search - * h: current page. - * key: key to find + * 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) +__bt_sprev(t, h, key, exactp) BTREE *t; PAGE *h; const DBT *key; int *exactp; { EPG e; - PAGE *tp; - pgno_t pg; - /* Skip until reach the beginning of the tree or a key. */ - for (pg = h->prevpg; pg != P_INVALID;) { - if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) { - mpool_put(t->bt_mp, h, 0); - return (NULL); - } - if (NEXTINDEX(tp) != 0) - break; - pg = tp->prevpg; - mpool_put(t->bt_mp, tp, 0); - } /* - * The key is either an exact match, or not as good as - * the one we already have. + * Get the previous page. The key is either an exact + * match, or not as good as the one we already have. */ - if (pg != P_INVALID) { - e.page = tp; - e.index = NEXTINDEX(tp) - 1; - if (__bt_cmp(t, key, &e) == 0) { - mpool_put(t->bt_mp, h, 0); - t->bt_cur = e; - *exactp = 1; - return (1); - } + 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.c b/db/btree/bt_seq.c index 6cd9ec0..db45e1f 100644 --- a/db/btree/bt_seq.c +++ b/db/btree/bt_seq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -69,24 +73,21 @@ #include #include "btree.h" -static int bt_seqadv __P((BTREE *, EPG *, int)); -static int bt_seqset __P((BTREE *, EPG *, DBT *, int)); +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. - * - * Each tree has an EPGNO which has the current position of the cursor. The - * cursor has to survive deletions/insertions in the tree without losing its - * position. This is done by noting deletions without doing them, and then - * doing them when the cursor moves (or the tree is closed). + * 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. + * __bt_seq -- + * Btree sequential scan interface. * * Parameters: * dbp: pointer to access method @@ -117,21 +118,21 @@ __bt_seq(dbp, key, data, flags) /* * 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. + * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin + * the page the cursor references if they're successful. */ - switch(flags) { + switch (flags) { case R_NEXT: case R_PREV: - if (ISSET(t, B_SEQINIT)) { - status = bt_seqadv(t, &e, flags); + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + status = __bt_seqadv(t, &e, flags); break; } /* FALLTHROUGH */ - case R_CURSOR: case R_FIRST: case R_LAST: - status = bt_seqset(t, &e, key, flags); + case R_CURSOR: + status = __bt_seqset(t, &e, key, flags); break; default: errno = EINVAL; @@ -139,27 +140,26 @@ __bt_seq(dbp, key, data, flags) } if (status == RET_SUCCESS) { - status = __bt_ret(t, &e, key, data); + __bt_setcur(t, e.page->pgno, e.index); - /* Update the actual cursor. */ - t->bt_bcursor.pgno = e.page->pgno; - t->bt_bcursor.index = 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 (ISSET(t, B_DB_LOCK)) + if (F_ISSET(t, B_DB_LOCK)) mpool_put(t->bt_mp, e.page, 0); else t->bt_pinned = e.page; - SET(t, B_SEQINIT); } return (status); } /* - * BT_SEQSET -- Set the sequential scan to a specific key. + * __bt_seqset -- + * Set the sequential scan to a specific key. * * Parameters: * t: tree @@ -174,87 +174,50 @@ __bt_seq(dbp, key, data, flags) * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ static int -bt_seqset(t, ep, key, flags) +__bt_seqset(t, ep, key, flags) BTREE *t; EPG *ep; DBT *key; int flags; { - EPG *e; PAGE *h; pgno_t pg; int exact; /* - * Delete any already deleted record that we've been saving because - * the cursor pointed to it. Since going to a specific key, should - * delete any logically deleted records so they aren't found. - */ - if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor)) - return (RET_ERROR); - - /* - * 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. + * 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) { + 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 run out - * of keys, return RET_SPECIAL. + * 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); } - e = __bt_first(t, key, &exact); /* Returns pinned page. */ - if (e == NULL) - return (RET_ERROR); - /* - * If at the end of a page, skip any empty pages and find the - * next entry. - */ - if (e->index == NEXTINDEX(e->page)) { - h = e->page; - do { - 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); - } while (NEXTINDEX(h) == 0); - e->index = 0; - e->page = h; - } - *ep = *e; - break; + 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); } - - /* Skip any empty pages. */ - while (NEXTINDEX(h) == 0 && h->nextpg != P_INVALID) { - pg = h->nextpg; - mpool_put(t->bt_mp, h, 0); - if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) - return (RET_ERROR); - } - - if (NEXTINDEX(h) == 0) { - mpool_put(t->bt_mp, h, 0); - return (RET_SPECIAL); - } - ep->page = h; ep->index = 0; break; @@ -264,25 +227,19 @@ bt_seqset(t, ep, key, flags) 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); } - /* Skip any empty pages. */ - while (NEXTINDEX(h) == 0 && h->prevpg != P_INVALID) { - pg = h->prevpg; - mpool_put(t->bt_mp, h, 0); - if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) - return (RET_ERROR); - } - - if (NEXTINDEX(h) == 0) { - mpool_put(t->bt_mp, h, 0); - return (RET_SPECIAL); - } - ep->page = h; ep->index = NEXTINDEX(h) - 1; break; @@ -291,7 +248,8 @@ bt_seqset(t, ep, key, flags) } /* - * BT_SEQADVANCE -- Advance the sequential scan. + * __bt_seqadvance -- + * Advance the sequential scan. * * Parameters: * t: tree @@ -304,98 +262,224 @@ bt_seqset(t, ep, key, flags) * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. */ static int -bt_seqadv(t, e, flags) +__bt_seqadv(t, ep, flags) BTREE *t; - EPG *e; + EPG *ep; int flags; { - EPGNO *c, delc; + CURSOR *c; PAGE *h; indx_t index; pgno_t pg; + int exact; - /* Save the current cursor if going to delete it. */ - c = &t->bt_bcursor; - if (ISSET(t, B_DELCRSR)) - delc = *c; + /* + * 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; - if ((h = mpool_get(t->bt_mp, c->pgno, 0)) == NULL) + /* + * 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. + * 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. */ - index = c->index; - switch(flags) { + 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)) { - do { - 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); - } while (NEXTINDEX(h) == 0); + 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. */ - if (index-- == 0) { - do { - 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); - } while (NEXTINDEX(h) == 0); - index = NEXTINDEX(h) - 1; + /* + * 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; } - e->page = h; - e->index = index; + 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; /* - * Delete any already deleted record that we've been saving because the - * cursor pointed to it. This could cause the new index to be shifted - * down by one if the record we're deleting is on the same page and has - * a larger index. + * 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 (ISSET(t, B_DELCRSR)) { - CLR(t, B_DELCRSR); /* Don't try twice. */ - if (c->pgno == delc.pgno && c->index > delc.index) - --c->index; - if (__bt_crsrdel(t, &delc)) + 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_CRSRDEL -- Delete the record referenced by the cursor. + * __bt_setcur -- + * Set the cursor to an entry in the tree. * * Parameters: - * t: tree - * - * Returns: - * RET_ERROR, RET_SUCCESS + * t: the tree + * pgno: page number + * index: page index */ -int -__bt_crsrdel(t, c) +void +__bt_setcur(t, pgno, index) BTREE *t; - EPGNO *c; + pgno_t pgno; + u_int index; { - PAGE *h; - int status; + /* 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); - CLR(t, B_DELCRSR); /* Don't try twice. */ - if ((h = mpool_get(t->bt_mp, c->pgno, 0)) == NULL) - return (RET_ERROR); - status = __bt_dleaf(t, h, c->index); - mpool_put(t->bt_mp, h, MPOOL_DIRTY); - return (status); + /* 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.c b/db/btree/bt_split.c index d1fdbe1..691fd46 100644 --- a/db/btree/bt_split.c +++ b/db/btree/bt_split.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -69,16 +73,13 @@ #include #include "btree.h" -static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *)); -static PAGE *bt_page - __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t)); -static int bt_preserve __P((BTREE *, pgno_t)); -static PAGE *bt_psplit - __P((BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t)); -static PAGE *bt_root - __P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t)); -static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *)); -static recno_t rec_total __P((PAGE *)); +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; @@ -100,13 +101,13 @@ u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved; * RET_ERROR, RET_SUCCESS */ int -__bt_split(t, sp, key, data, flags, ilen, skip) +__bt_split(t, sp, key, data, flags, ilen, argskip) BTREE *t; PAGE *sp; const DBT *key, *data; int flags; size_t ilen; - indx_t skip; + u_int32_t argskip; { BINTERNAL *bi; BLEAF *bl, *tbl; @@ -114,7 +115,8 @@ __bt_split(t, sp, key, data, flags, ilen, skip) EPGNO *parent; PAGE *h, *l, *r, *lchild, *rchild; indx_t nxtindex; - size_t n, nbytes, nksize; + u_int16_t skip; + u_int32_t n, nbytes, nksize; int parentsplit; char *dest; @@ -124,6 +126,7 @@ __bt_split(t, sp, key, data, flags, ilen, skip) * 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); @@ -136,14 +139,14 @@ __bt_split(t, sp, key, data, flags, ilen, skip) */ h->linp[skip] = h->upper -= ilen; dest = (char *)h + h->upper; - if (ISSET(t, R_RECNO)) + 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 && - (ISSET(t, R_RECNO) ? + (F_ISSET(t, R_RECNO) ? bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR) goto err2; @@ -251,7 +254,7 @@ __bt_split(t, sp, key, data, flags, ilen, skip) } /* Insert the key into the parent page. */ - switch(rchild->flags & P_TYPE) { + switch (rchild->flags & P_TYPE) { case P_BINTERNAL: h->linp[skip] = h->upper -= nbytes; dest = (char *)h + h->linp[skip]; @@ -316,7 +319,7 @@ __bt_split(t, sp, key, data, flags, ilen, skip) /* If the root page was split, make it look right. */ if (sp->pgno == P_ROOT && - (ISSET(t, R_RECNO) ? + (F_ISSET(t, R_RECNO) ? bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR) goto err1; @@ -409,6 +412,9 @@ bt_page(t, h, lp, rp, skip, ilen) 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; @@ -424,7 +430,7 @@ bt_page(t, h, lp, rp, skip, ilen) return (NULL); } tp->prevpg = r->pgno; - mpool_put(t->bt_mp, tp, 0); + mpool_put(t->bt_mp, tp, MPOOL_DIRTY); } /* @@ -555,7 +561,7 @@ bt_broot(t, h, l, r) { BINTERNAL *bi; BLEAF *bl; - size_t nbytes; + u_int32_t nbytes; char *dest; /* @@ -571,7 +577,7 @@ bt_broot(t, h, l, r) dest = (char *)h + h->upper; WR_BINTERNAL(dest, 0, l->pgno, 0); - switch(h->flags & P_TYPE) { + switch (h->flags & P_TYPE) { case P_BLEAF: bl = GETBLEAF(r, 0); nbytes = NBINTERNAL(bl->ksize); @@ -634,12 +640,12 @@ bt_psplit(t, h, l, r, pskip, ilen) { BINTERNAL *bi; BLEAF *bl; + CURSOR *c; RLEAF *rl; - EPGNO *c; PAGE *rval; void *src; indx_t full, half, nxt, off, skip, top, used; - size_t nbytes; + u_int32_t nbytes; int bigkeycnt, isbigkey; /* @@ -689,7 +695,8 @@ bt_psplit(t, h, l, r, pskip, ilen) * where we decide to try and copy too much onto the left page. * Make sure that doesn't happen. */ - if (skip <= off && used + nbytes >= full) { + if ((skip <= off && used + nbytes + sizeof(indx_t) >= full) + || nxt == top - 1) { --off; break; } @@ -702,7 +709,7 @@ bt_psplit(t, h, l, r, pskip, ilen) memmove((char *)l + l->upper, src, nbytes); } - used += nbytes; + used += nbytes + sizeof(indx_t); if (used >= half) { if (!isbigkey || bigkeycnt == 3) break; @@ -723,19 +730,16 @@ bt_psplit(t, h, l, r, pskip, ilen) * 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. - * - * Don't bother checking for the B_SEQINIT flag, the page number will - * be P_INVALID. */ - c = &t->bt_bcursor; - if (c->pgno == h->pgno) { - if (c->index >= skip) - ++c->index; - if (c->index < nxt) /* Left page. */ - c->pgno = l->pgno; + 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->pgno = r->pgno; - c->index -= nxt; + c->pg.pgno = r->pgno; + c->pg.index -= nxt; } } diff --git a/db/btree/bt_utils.c b/db/btree/bt_utils.c index 05b421f..a2b086b 100644 --- a/db/btree/bt_utils.c +++ b/db/btree/bt_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -69,78 +73,91 @@ #include "btree.h" /* - * __BT_RET -- Build return key/data pair as a result of search or scan. + * __bt_ret -- + * Build return key/data pair. * * Parameters: * t: tree - * d: LEAF to be returned to the user. + * e: key/data pair to be returned * key: user's key structure (NULL if not to be filled in) - * data: user's data structure + * 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, data) +__bt_ret(t, e, key, rkey, data, rdata, copy) BTREE *t; EPG *e; - DBT *key, *data; + DBT *key, *rkey, *data, *rdata; + int copy; { - register BLEAF *bl; - register void *p; + BLEAF *bl; + void *p; bl = GETBLEAF(e->page, e->index); /* - * We always copy big keys/data to make them contigous. Otherwise, - * we leave the page pinned and don't copy unless the user specified + * 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 (bl->flags & P_BIGDATA) { - if (__ovfl_get(t, bl->bytes + bl->ksize, - &data->size, &t->bt_dbuf, &t->bt_dbufsz)) + 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); - data->data = t->bt_dbuf; - } else if (ISSET(t, B_DB_LOCK)) { - /* Use +1 in case the first record retrieved is 0 length. */ - if (bl->dsize + 1 > t->bt_dbufsz) { - if ((p = - (void *)realloc(t->bt_dbuf, bl->dsize + 1)) == NULL) + 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); - t->bt_dbuf = p; - t->bt_dbufsz = bl->dsize + 1; + rkey->data = p; + rkey->size = bl->ksize; } - memmove(t->bt_dbuf, bl->bytes + bl->ksize, bl->dsize); - data->size = bl->dsize; - data->data = t->bt_dbuf; + memmove(rkey->data, bl->bytes, bl->ksize); + key->size = bl->ksize; + key->data = rkey->data; } else { - data->size = bl->dsize; - data->data = bl->bytes + bl->ksize; + key->size = bl->ksize; + key->data = bl->bytes; } - if (key == NULL) +dataonly: + if (data == NULL) return (RET_SUCCESS); - if (bl->flags & P_BIGKEY) { - if (__ovfl_get(t, bl->bytes, - &key->size, &t->bt_kbuf, &t->bt_kbufsz)) + if (bl->flags & P_BIGDATA) { + if (__ovfl_get(t, bl->bytes + bl->ksize, + &data->size, &rdata->data, &rdata->size)) return (RET_ERROR); - key->data = t->bt_kbuf; - } else if (ISSET(t, B_DB_LOCK)) { - if (bl->ksize > t->bt_kbufsz) { - if ((p = - (void *)realloc(t->bt_kbuf, bl->ksize)) == NULL) + 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); - t->bt_kbuf = p; - t->bt_kbufsz = bl->ksize; + rdata->data = p; + rdata->size = bl->dsize + 1; } - memmove(t->bt_kbuf, bl->bytes, bl->ksize); - key->size = bl->ksize; - key->data = t->bt_kbuf; + memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize); + data->size = bl->dsize; + data->data = rdata->data; } else { - key->size = bl->ksize; - key->data = bl->bytes; + data->size = bl->dsize; + data->data = bl->bytes + bl->ksize; } + return (RET_SUCCESS); } @@ -201,9 +218,9 @@ __bt_cmp(t, k1, e) if (bigkey) { if (__ovfl_get(t, bigkey, - &k2.size, &t->bt_dbuf, &t->bt_dbufsz)) + &k2.size, &t->bt_rdata.data, &t->bt_rdata.size)) return (RET_ERROR); - k2.data = t->bt_dbuf; + k2.data = t->bt_rdata.data; } return ((*t->bt_cmp)(k1, &k2)); } @@ -224,13 +241,13 @@ int __bt_defcmp(a, b) const DBT *a, *b; { - register size_t len; - register u_char *p1, *p2; + 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 a integral type which is guaranteed to be + * 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); @@ -254,8 +271,8 @@ size_t __bt_defpfx(a, b) const DBT *a, *b; { - register u_char *p1, *p2; - register size_t cnt, len; + u_char *p1, *p2; + size_t cnt, len; cnt = 1; len = MIN(a->size, b->size); diff --git a/db/btree/btree.h b/db/btree/btree.h index fca4b3c..a575f68 100644 --- a/db/btree/btree.h +++ b/db/btree/btree.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1991, 1993 +/*- + * 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 @@ -56,8 +56,16 @@ * LIABILITY, OR TORT (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 */ @@ -101,8 +109,9 @@ typedef struct _page { } 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 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)) /* @@ -121,9 +130,8 @@ typedef struct _page { * 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(size_t)) +#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} @@ -135,7 +143,7 @@ typedef struct _page { * some minor modifications of the above rule. */ typedef struct _binternal { - size_t ksize; /* key size */ + 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 */ @@ -144,21 +152,21 @@ typedef struct _binternal { } BINTERNAL; /* Get the page's BINTERNAL structure at index indx. */ -#define GETBINTERNAL(pg, indx) \ +#define GETBINTERNAL(pg, indx) \ ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx])) /* Get the number of bytes in the entry. */ -#define NBINTERNAL(len) \ - LALIGN(sizeof(size_t) + sizeof(pgno_t) + sizeof(u_char) + (len)) +#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) { \ - *(size_t *)p = size; \ - p += sizeof(size_t); \ - *(pgno_t *)p = pgno; \ - p += sizeof(pgno_t); \ - *(u_char *)p = flags; \ - p += sizeof(u_char); \ +#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); \ } /* @@ -171,78 +179,78 @@ typedef struct _rinternal { } RINTERNAL; /* Get the page's RINTERNAL structure at index indx. */ -#define GETRINTERNAL(pg, indx) \ +#define GETRINTERNAL(pg, indx) \ ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx])) /* Get the number of bytes in the entry. */ -#define NRINTERNAL \ +#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; \ +#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 { - size_t ksize; /* size of key */ - size_t dsize; /* size of data */ + 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) \ +#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(size_t) + sizeof(size_t) + sizeof(u_char) + \ +#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) { \ - *(size_t *)p = key->size; \ - p += sizeof(size_t); \ - *(size_t *)p = data->size; \ - p += sizeof(size_t); \ - *(u_char *)p = flags; \ - p += sizeof(u_char); \ - memmove(p, key->data, key->size); \ - p += key->size; \ - memmove(p, data->data, data->size); \ +#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 { - size_t dsize; /* size of data */ + 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) \ +#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(size_t) + sizeof(u_char) + (dsize)) +#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) { \ - *(size_t *)p = data->size; \ - p += sizeof(size_t); \ - *(u_char *)p = flags; \ - p += sizeof(u_char); \ - memmove(p, data->data, data->size); \ +#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); \ } /* @@ -254,12 +262,6 @@ typedef struct _rleaf { * 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. - * - * One comment about cursors. The cursor key is never removed from the tree, - * even if deleted. This is because it is quite difficult to decide where the - * cursor should be when other keys have been inserted/deleted in the tree; - * duplicate keys make it impossible. This scheme does require extra work - * though, to make sure that we don't perform an operation on a deleted key. */ typedef struct _epgno { pgno_t pgno; /* the page number */ @@ -272,104 +274,135 @@ typedef struct _epg { } EPG; /* - * The metadata of the tree. The m_nrecs field is used only by the RECNO code. + * 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 m_magic; /* magic number */ - u_int32_t m_version; /* version */ - u_int32_t m_psize; /* page size */ - u_int32_t m_free; /* page number of first free page */ - u_int32_t m_nrecs; /* R: number of records */ + 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 m_flags; /* bt_flags & SAVEMETA */ - u_int32_t m_unused; /* unused */ + u_int32_t flags; /* bt_flags & SAVEMETA */ } BTMETA; /* The in-memory btree/recno data structure. */ typedef struct _btree { - MPOOL *bt_mp; /* memory pool cookie */ + MPOOL *bt_mp; /* memory pool cookie */ - DB *bt_dbp; /* pointer to enclosing DB */ + DB *bt_dbp; /* pointer to enclosing DB */ - EPG bt_cur; /* current (pinned) page */ - PAGE *bt_pinned; /* page pinned across calls */ + EPG bt_cur; /* current (pinned) page */ + PAGE *bt_pinned; /* page pinned across calls */ - EPGNO bt_bcursor; /* B: btree cursor */ - recno_t bt_rcursor; /* R: recno cursor (1-based) */ + CURSOR bt_cursor; /* cursor */ -#define BT_POP(t) (t->bt_sp ? t->bt_stack + --t->bt_sp : NULL) -#define BT_CLR(t) (t->bt_sp = 0) - EPGNO *bt_stack; /* stack of parent pages */ - u_int bt_sp; /* current stack pointer */ - u_int bt_maxstack; /* largest stack */ +#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 */ - char *bt_kbuf; /* key buffer */ - size_t bt_kbufsz; /* key buffer size */ - char *bt_dbuf; /* data buffer */ - size_t bt_dbufsz; /* data buffer size */ + DBT bt_rkey; /* returned key */ + DBT bt_rdata; /* returned data */ - int bt_fd; /* tree file descriptor */ + int bt_fd; /* tree file descriptor */ - pgno_t bt_free; /* next free page */ + 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 */ + 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 */ + EPGNO bt_last; /* last insert */ /* B: key comparison function */ - int (*bt_cmp) __P((const DBT *, const DBT *)); + int (*bt_cmp)(const DBT *, const DBT *); /* B: prefix comparison function */ - size_t (*bt_pfx) __P((const DBT *, const DBT *)); + size_t (*bt_pfx)(const DBT *, const DBT *); /* R: recno input function */ - int (*bt_irec) __P((struct _btree *, recno_t)); + int (*bt_irec)(struct _btree *, recno_t); - FILE *bt_rfp; /* R: record FILE pointer */ - int bt_rfd; /* R: record file descriptor */ + 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. */ + 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 */ + 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_DELCRSR 0x00001 /* cursor has been deleted */ -#define B_INMEM 0x00002 /* in-memory tree */ -#define B_METADIRTY 0x00004 /* need to write metadata */ -#define B_MODIFIED 0x00008 /* tree modified */ -#define B_NEEDSWAP 0x00010 /* if byte order requires swapping */ +#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 B_RDONLY 0x00040 /* read-only tree */ #define R_RECNO 0x00080 /* record oriented tree */ -#define B_SEQINIT 0x00100 /* sequential scan initialized */ -#define R_CLOSEFP 0x00200 /* opened a file pointer */ -#define R_EOF 0x00400 /* end of input file reached. */ -#define R_FIXLEN 0x00800 /* fixed length records */ -#define R_MEMMAPPED 0x01000 /* memory mapped file. */ -#define R_INMEM 0x02000 /* in-memory file */ -#define R_MODIFIED 0x04000 /* modified file */ -#define R_RDONLY 0x08000 /* read-only file */ - -#define B_DB_LOCK 0x10000 /* DB_LOCK specified. */ -#define B_DB_SHMEM 0x20000 /* DB_SHMEM specified. */ -#define B_DB_TXN 0x40000 /* DB_TXN specified. */ - - u_int32_t bt_flags; /* btree state */ +#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; -#define SET(t, f) ((t)->bt_flags |= (f)) -#define CLR(t, f) ((t)->bt_flags &= ~(f)) -#define ISSET(t, f) ((t)->bt_flags & (f)) - -#include "bt_extern.h" +#include "extern.h" diff --git a/gen/sethostname.c b/db/btree/extern.h similarity index 66% rename from gen/sethostname.c rename to db/btree/extern.h index d65c4c6..a24178c 100644 --- a/gen/sethostname.c +++ b/db/btree/extern.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1989, 1993 +/*- + * 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 @@ -53,28 +53,43 @@ * LIABILITY, OR TORT (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 $ */ -#include -#include - -#if __STDC__ -long -sethostname(const char *name, int namelen) -#else -long -sethostname(name, namelen) - char *name; - int namelen; -#endif -{ - 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); -} +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/db/db.c b/db/db/db.c index 9e726b2..9dabe62 100644 --- a/db/db/db.c +++ b/db/db/db.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* +/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -55,6 +55,10 @@ * 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 #include diff --git a/db/hash/Makefile.inc b/db/hash/Makefile.inc index b5874e8..45f5d8d 100644 --- a/db/hash/Makefile.inc +++ b/db/hash/Makefile.inc @@ -4,4 +4,4 @@ .PATH: ${.CURDIR}/db/hash SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ - hash_page.c ndbm.c hsearch.c + hash_page.c ndbm.c diff --git a/db/hash/extern.h b/db/hash/extern.h index 2e5edd5..3f25acc 100644 --- a/db/hash/extern.h +++ b/db/hash/extern.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1991, 1993 +/*- + * 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 @@ -53,35 +53,38 @@ * LIABILITY, OR TORT (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 __P((HTAB *, BUFHEAD *)); -int __addel __P((HTAB *, BUFHEAD *, const DBT *, const DBT *)); -int __big_delete __P((HTAB *, BUFHEAD *)); -int __big_insert __P((HTAB *, BUFHEAD *, const DBT *, const DBT *)); -int __big_keydata __P((HTAB *, BUFHEAD *, DBT *, DBT *, int)); -int __big_return __P((HTAB *, BUFHEAD *, int, DBT *, int)); -int __big_split __P((HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *, - int, u_int, SPLIT_RETURN *)); -int __buf_free __P((HTAB *, int, int)); -void __buf_init __P((HTAB *, int)); -u_int __call_hash __P((HTAB *, char *, int)); -int __delpair __P((HTAB *, BUFHEAD *, int)); -int __expand_table __P((HTAB *)); -int __find_bigpair __P((HTAB *, BUFHEAD *, int, char *, int)); -u_short __find_last_page __P((HTAB *, BUFHEAD **)); -void __free_ovflpage __P((HTAB *, BUFHEAD *)); -BUFHEAD *__get_buf __P((HTAB *, u_int, BUFHEAD *, int)); -int __get_page __P((HTAB *, char *, u_int, int, int, int)); -int __init_bitmap __P((HTAB *, int, int, int)); -u_int __log2 __P((u_int)); -int __put_page __P((HTAB *, char *, u_int, int, int)); -void __reclaim_buf __P((HTAB *, BUFHEAD *)); -int __split_page __P((HTAB *, u_int, u_int)); +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) __P((const void *, size_t)); +extern u_int32_t (*__default_hash)(const void *, size_t); #ifdef HASH_STATISTICS -extern long hash_accesses, hash_collisions, hash_expansions, hash_overflows; +extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows; #endif diff --git a/db/hash/hash.c b/db/hash/hash.c index 8ba3c8f..84da4d9 100644 --- a/db/hash/hash.c +++ b/db/hash/hash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include #include @@ -77,23 +81,23 @@ #include "page.h" #include "extern.h" -static int alloc_segs __P((HTAB *, int)); -static int flush_meta __P((HTAB *)); -static int hash_access __P((HTAB *, ACTION, DBT *, DBT *)); -static int hash_close __P((DB *)); -static int hash_delete __P((const DB *, const DBT *, u_int)); -static int hash_fd __P((const DB *)); -static int hash_get __P((const DB *, const DBT *, DBT *, u_int)); -static int hash_put __P((const DB *, DBT *, const DBT *, u_int)); -static void *hash_realloc __P((SEGMENT **, int, int)); -static int hash_seq __P((const DB *, DBT *, DBT *, u_int)); -static int hash_sync __P((const DB *, u_int)); -static int hdestroy __P((HTAB *)); -static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *)); -static int init_htab __P((HTAB *, int)); +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 __P((HTAB *)); -static void swap_header_copy __P((HASHHDR *, HASHHDR *)); +static void swap_header(HTAB *); +static void swap_header_copy(HASHHDR *, HASHHDR *); #endif /* Fast arithmetic, relying on powers of 2, */ @@ -107,7 +111,7 @@ static void swap_header_copy __P((HASHHDR *, HASHHDR *)); #define ABNORMAL (1) #ifdef HASH_STATISTICS -long hash_accesses, hash_collisions, hash_expansions, hash_overflows; +int hash_accesses, hash_collisions, hash_expansions, hash_overflows; #endif /************************** INTERFACE ROUTINES ***************************/ @@ -151,6 +155,13 @@ __hash_open(file, flags, mode, info, dflags) 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) { @@ -200,7 +211,7 @@ __hash_open(file, flags, mode, info, dflags) (hashp->BSHIFT + BYTE_SHIFT); hashp->nmaps = bpages; - (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_long *)); + (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *)); } /* Initialize Buffer Manager */ @@ -368,7 +379,7 @@ init_htab(hashp, nelem) HTAB *hashp; int nelem; { - register int nbuckets, nsegs; + int nbuckets, nsegs; int l2; /* @@ -387,7 +398,7 @@ init_htab(hashp, nelem) hashp->LAST_FREED = 2; /* First bitmap page is at: splitpoint l2 page offset 1 */ - if (__init_bitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0)) + if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0)) return (-1); hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1; @@ -472,7 +483,7 @@ hdestroy(hashp) static int hash_sync(dbp, flags) const DB *dbp; - u_int flags; + u_int32_t flags; { HTAB *hashp; @@ -551,7 +562,7 @@ hash_get(dbp, key, data, flag) const DB *dbp; const DBT *key; DBT *data; - u_int flag; + u_int32_t flag; { HTAB *hashp; @@ -568,13 +579,14 @@ hash_put(dbp, key, data, flag) const DB *dbp; DBT *key; const DBT *data; - u_int flag; + u_int32_t flag; { HTAB *hashp; hashp = (HTAB *)dbp->internal; if (flag && flag != R_NOOVERWRITE) { - hashp->error = errno = EINVAL; + hashp->error = EINVAL; + errno = EINVAL; return (ERROR); } if ((hashp->flags & O_ACCMODE) == O_RDONLY) { @@ -589,7 +601,7 @@ static int hash_delete(dbp, key, flag) const DB *dbp; const DBT *key; - u_int flag; /* Ignored */ + u_int32_t flag; /* Ignored */ { HTAB *hashp; @@ -614,12 +626,12 @@ hash_access(hashp, action, key, val) ACTION action; DBT *key, *val; { - register BUFHEAD *rbufp; + BUFHEAD *rbufp; BUFHEAD *bufp, *save_bufp; - register u_short *bp; - register int n, ndx, off, size; - register char *kp; - u_short pageno; + u_int16_t *bp; + int n, ndx, off, size; + char *kp; + u_int16_t pageno; #ifdef HASH_STATISTICS hash_accesses++; @@ -635,7 +647,7 @@ hash_access(hashp, action, key, val) /* Pin the bucket chain */ rbufp->flags |= BUF_PIN; - for (bp = (u_short *)rbufp->page, n = *bp++, ndx = 1; ndx < n;) + 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 && @@ -654,7 +666,7 @@ hash_access(hashp, action, key, val) return (ERROR); } /* FOR LOOP INIT */ - bp = (u_short *)rbufp->page; + bp = (u_int16_t *)rbufp->page; n = *bp++; ndx = 1; off = hashp->BSIZE; @@ -676,7 +688,7 @@ hash_access(hashp, action, key, val) return (ERROR); } /* FOR LOOP INIT */ - bp = (u_short *)rbufp->page; + bp = (u_int16_t *)rbufp->page; n = *bp++; ndx = 1; off = hashp->BSIZE; @@ -710,7 +722,7 @@ found: save_bufp->flags &= ~BUF_PIN; return (ABNORMAL); case HASH_GET: - bp = (u_short *)rbufp->page; + bp = (u_int16_t *)rbufp->page; if (bp[ndx + 1] < REAL_KEY) { if (__big_return(hashp, rbufp, ndx, val, 0)) return (ERROR); @@ -741,12 +753,12 @@ static int hash_seq(dbp, key, data, flag) const DB *dbp; DBT *key, *data; - u_int flag; + u_int32_t flag; { - register u_int bucket; - register BUFHEAD *bufp; + u_int32_t bucket; + BUFHEAD *bufp; HTAB *hashp; - u_short *bp, ndx; + u_int16_t *bp, ndx; hashp = (HTAB *)dbp->internal; if (flag && flag != R_FIRST && flag != R_NEXT) { @@ -771,7 +783,7 @@ hash_seq(dbp, key, data, flag) if (!bufp) return (ERROR); hashp->cpage = bufp; - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; if (bp[0]) break; } @@ -781,7 +793,7 @@ hash_seq(dbp, key, data, flag) return (ABNORMAL); } } else - bp = (u_short *)hashp->cpage->page; + bp = (u_int16_t *)hashp->cpage->page; #ifdef DEBUG assert(bp); @@ -792,7 +804,7 @@ hash_seq(dbp, key, data, flag) __get_buf(hashp, bp[hashp->cndx], bufp, 0); if (!bufp) return (ERROR); - bp = (u_short *)(bufp->page); + bp = (u_int16_t *)(bufp->page); hashp->cndx = 1; } if (!bp[0]) { @@ -831,7 +843,7 @@ extern int __expand_table(hashp) HTAB *hashp; { - u_int old_bucket, new_bucket; + u_int32_t old_bucket, new_bucket; int dirsize, new_segnum, spare_ndx; #ifdef HASH_STATISTICS @@ -887,9 +899,9 @@ hash_realloc(p_ptr, oldsize, newsize) SEGMENT **p_ptr; int oldsize, newsize; { - register void *p; + void *p; - if (p = malloc(newsize)) { + if ( (p = malloc(newsize)) ) { memmove(p, *p_ptr, oldsize); memset((char *)p + oldsize, 0, newsize - oldsize); free(*p_ptr); @@ -898,7 +910,7 @@ hash_realloc(p_ptr, oldsize, newsize) return (p); } -extern u_int +extern u_int32_t __call_hash(hashp, k, len) HTAB *hashp; char *k; @@ -923,8 +935,8 @@ alloc_segs(hashp, nsegs) HTAB *hashp; int nsegs; { - register int i; - register SEGMENT store; + int i; + SEGMENT store; int save_errno; diff --git a/db/hash/hash.h b/db/hash/hash.h index 292000f..d2f0255 100644 --- a/db/hash/hash.h +++ b/db/hash/hash.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -56,6 +56,9 @@ * LIABILITY, OR TORT (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 */ @@ -67,12 +70,12 @@ typedef enum { typedef struct _bufhead BUFHEAD; struct _bufhead { - BUFHEAD *prev; /* LRU links */ - BUFHEAD *next; /* LRU links */ - BUFHEAD *ovfl; /* Overflow page buffer header */ - u_int addr; /* Address of this page */ - char *page; /* Actual page data */ - char flags; + 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 @@ -84,51 +87,60 @@ struct _bufhead { typedef BUFHEAD **SEGMENT; /* Hash Table Information */ -typedef struct hashhdr { /* Disk resident portion */ - int magic; /* Magic NO for hash tables */ - int version; /* Version ID */ - long 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_short bitmaps[NCACHED]; /* address of overflow page bitmaps */ +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)__P((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 compatability */ - int new_file; /* Indicates if fd is backing store or no */ - int save_file; /* Indicates whether we need to flush file at - * exit */ - u_long *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 */ +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 */ } HTAB; /* @@ -151,14 +163,14 @@ typedef struct htab { /* Memory resident data structure */ #define BYTE_SHIFT 3 #define INT_TO_BYTE 2 #define INT_BYTE_SHIFT 5 -#define ALL_SET ((u_int)0xFFFFFFFF) +#define ALL_SET ((u_int32_t)0xFFFFFFFF) #define ALL_CLEAR 0 -#define PTROF(X) ((BUFHEAD *)((u_int)(X)&~0x3)) -#define ISMOD(X) ((u_int)(X)&0x1) -#define DOMOD(X) ((X) = (char *)((u_int)(X)|0x1)) -#define ISDISK(X) ((u_int)(X)&0x2) -#define DODISK(X) ((X) = (char *)((u_int)(X)|0x2)) +#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 @@ -178,9 +190,9 @@ typedef struct htab { /* Memory resident data structure */ #define SPLITSHIFT 11 #define SPLITMASK 0x7FF -#define SPLITNUM(N) (((u_int)(N)) >> SPLITSHIFT) +#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT) #define OPAGENUM(N) ((N) & SPLITMASK) -#define OADDR_OF(S,O) ((u_int)((u_int)(S) << SPLITSHIFT) + (O)) +#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) @@ -207,7 +219,7 @@ typedef struct htab { /* Memory resident data structure */ * 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 @@ -242,7 +254,7 @@ typedef struct htab { /* Memory resident data structure */ * OVFL_PAGENO - page number of the next overflow page * OVFLPAGE -- 0 * - * FULL_KEY_DATA + * FULL_KEY_DATA * This must be the first key/data pair on the page. * There are two cases: * diff --git a/db/hash/hash_bigkey.c b/db/hash/hash_bigkey.c index fa8e8dd..3d1713b 100644 --- a/db/hash/hash_bigkey.c +++ b/db/hash/hash_bigkey.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 /* * PACKAGE: hash @@ -93,8 +97,8 @@ #include "page.h" #include "extern.h" -static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int)); -static int collect_data __P((HTAB *, BUFHEAD *, int, int)); +static int collect_key(HTAB *, BUFHEAD *, int, DBT *, int); +static int collect_data(HTAB *, BUFHEAD *, int, int); /* * Big_insert @@ -111,13 +115,13 @@ __big_insert(hashp, bufp, key, val) BUFHEAD *bufp; const DBT *key, *val; { - register u_short *p; + u_int16_t *p; int key_size, n, val_size; - u_short space, move_bytes, off; + u_int16_t space, move_bytes, off; char *cp, *key_data, *val_data; cp = bufp->page; /* Character pointer of p. */ - p = (u_short *)cp; + p = (u_int16_t *)cp; key_data = (char *)key->data; key_size = key->size; @@ -142,7 +146,7 @@ __big_insert(hashp, bufp, key, val) if (!bufp) return (-1); n = p[0]; - if (!key_size) + if (!key_size) { if (FREESPACE(p)) { move_bytes = MIN(FREESPACE(p), val_size); off = OFFSET(p) - move_bytes; @@ -155,7 +159,8 @@ __big_insert(hashp, bufp, key, val) OFFSET(p) = off; } else p[n - 2] = FULL_KEY; - p = (u_short *)bufp->page; + } + p = (u_int16_t *)bufp->page; cp = bufp->page; bufp->flags |= BUF_MOD; } @@ -185,7 +190,7 @@ __big_insert(hashp, bufp, key, val) if (!bufp) return (-1); cp = bufp->page; - p = (u_short *)cp; + p = (u_int16_t *)cp; } else p[n] = FULL_KEY_DATA; bufp->flags |= BUF_MOD; @@ -209,13 +214,13 @@ __big_delete(hashp, bufp) HTAB *hashp; BUFHEAD *bufp; { - register BUFHEAD *last_bfp, *rbufp; - u_short *bp, pageno; + BUFHEAD *last_bfp, *rbufp; + u_int16_t *bp, pageno; int key_done, n; rbufp = bufp; last_bfp = NULL; - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; pageno = 0; key_done = 0; @@ -238,7 +243,7 @@ __big_delete(hashp, bufp) last_bfp = rbufp; if (!rbufp) return (-1); /* Error. */ - bp = (u_short *)rbufp->page; + bp = (u_int16_t *)rbufp->page; } /* @@ -253,7 +258,7 @@ __big_delete(hashp, bufp) pageno = bp[n - 1]; /* Now, bp is the first page of the pair. */ - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; if (n > 2) { /* There is an overflow page. */ bp[1] = pageno; @@ -291,13 +296,13 @@ __find_bigpair(hashp, bufp, ndx, key, size) char *key; int size; { - register u_short *bp; - register char *p; + u_int16_t *bp; + char *p; int ksize; - u_short bytes; + u_int16_t bytes; char *kkey; - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; p = bufp->page; ksize = size; kkey = key; @@ -313,7 +318,7 @@ __find_bigpair(hashp, bufp, ndx, key, size) if (!bufp) return (-3); p = bufp->page; - bp = (u_short *)p; + bp = (u_int16_t *)p; ndx = 1; } @@ -335,17 +340,17 @@ __find_bigpair(hashp, bufp, ndx, key, size) * of the pair; 0 if there isn't any (i.e. big pair is the last key in the * bucket) */ -extern u_short +extern u_int16_t __find_last_page(hashp, bpp) HTAB *hashp; BUFHEAD **bpp; { BUFHEAD *bufp; - u_short *bp, pageno; + u_int16_t *bp, pageno; int n; bufp = *bpp; - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; for (;;) { n = bp[0]; @@ -362,7 +367,7 @@ __find_last_page(hashp, bpp) bufp = __get_buf(hashp, pageno, bufp, 0); if (!bufp) return (0); /* Need to indicate an error! */ - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; } *bpp = bufp; @@ -385,15 +390,15 @@ __big_return(hashp, bufp, ndx, val, set_current) int set_current; { BUFHEAD *save_p; - u_short *bp, len, off, save_addr; + u_int16_t *bp, len, off, save_addr; char *tp; - bp = (u_short *)bufp->page; + 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_short *)bufp->page; + bp = (u_int16_t *)bufp->page; ndx = 1; } @@ -401,7 +406,7 @@ __big_return(hashp, bufp, ndx, val, set_current) bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; save_p = bufp; save_addr = save_p->addr; off = bp[1]; @@ -422,7 +427,7 @@ __big_return(hashp, bufp, ndx, val, set_current) bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; } else { /* The data is all on one page. */ tp = (char *)bp; @@ -441,7 +446,7 @@ __big_return(hashp, bufp, ndx, val, set_current) if (!hashp->cpage) return (-1); hashp->cndx = 1; - if (!((u_short *) + if (!((u_int16_t *) hashp->cpage->page)[0]) { hashp->cbucket++; hashp->cpage = NULL; @@ -473,14 +478,14 @@ collect_data(hashp, bufp, len, set) BUFHEAD *bufp; int len, set; { - register u_short *bp; - register char *p; + u_int16_t *bp; + char *p; BUFHEAD *xbp; - u_short save_addr; + u_int16_t save_addr; int mylen, totlen; p = bufp->page; - bp = (u_short *)p; + bp = (u_int16_t *)p; mylen = hashp->BSIZE - bp[1]; save_addr = bufp->addr; @@ -500,7 +505,7 @@ collect_data(hashp, bufp, len, set) __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!hashp->cpage) return (-1); - else if (!((u_short *)hashp->cpage->page)[0]) { + else if (!((u_int16_t *)hashp->cpage->page)[0]) { hashp->cbucket++; hashp->cpage = NULL; } @@ -552,10 +557,10 @@ collect_key(hashp, bufp, len, val, set) BUFHEAD *xbp; char *p; int mylen, totlen; - u_short *bp, save_addr; + u_int16_t *bp, save_addr; p = bufp->page; - bp = (u_short *)p; + bp = (u_int16_t *)p; mylen = hashp->BSIZE - bp[1]; save_addr = bufp->addr; @@ -594,15 +599,15 @@ __big_split(hashp, op, np, big_keyp, addr, obucket, ret) /* Pointer to first page containing the big key/data */ BUFHEAD *big_keyp; int addr; /* Address of big_keyp */ - u_int obucket;/* Old Bucket */ + u_int32_t obucket;/* Old Bucket */ SPLIT_RETURN *ret; { - register BUFHEAD *tmpp; - register u_short *tp; + BUFHEAD *tmpp; + u_int16_t *tp; BUFHEAD *bp; DBT key, val; - u_int change; - u_short free_space, n, off; + u_int32_t change; + u_int16_t free_space, n, off; bp = big_keyp; @@ -611,7 +616,7 @@ __big_split(hashp, op, np, big_keyp, addr, obucket, ret) return (-1); change = (__call_hash(hashp, key.data, key.size) != obucket); - if (ret->next_addr = __find_last_page(hashp, &big_keyp)) { + if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) { if (!(ret->nextp = __get_buf(hashp, ret->next_addr, big_keyp, 0))) return (-1);; @@ -634,14 +639,14 @@ __big_split(hashp, op, np, big_keyp, addr, obucket, ret) (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0)); #endif tmpp->ovfl = bp; /* one of op/np point to big_keyp */ - tp = (u_short *)tmpp->page; + 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_short)addr; + tp[++n] = (u_int16_t)addr; tp[++n] = OVFLPAGE; tp[0] = n; OFFSET(tp) = off; @@ -657,7 +662,7 @@ __big_split(hashp, op, np, big_keyp, addr, obucket, ret) ret->newp = np; ret->oldp = op; - tp = (u_short *)big_keyp->page; + tp = (u_int16_t *)big_keyp->page; big_keyp->flags |= BUF_MOD; if (tp[0] > 2) { /* diff --git a/db/hash/hash_buf.c b/db/hash/hash_buf.c index 1c187e5..327cce3 100644 --- a/db/hash/hash_buf.c +++ b/db/hash/hash_buf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 /* * PACKAGE: hash @@ -77,9 +81,10 @@ #include -#include +#include #include #include + #ifdef DEBUG #include #endif @@ -89,7 +94,7 @@ #include "page.h" #include "extern.h" -static BUFHEAD *newbuf __P((HTAB *, u_int, BUFHEAD *)); +static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *); /* Unlink B from its place in the lru */ #define BUF_REMOVE(B) { \ @@ -123,13 +128,13 @@ static BUFHEAD *newbuf __P((HTAB *, u_int, BUFHEAD *)); extern BUFHEAD * __get_buf(hashp, addr, prev_bp, newpage) HTAB *hashp; - u_int addr; + u_int32_t addr; BUFHEAD *prev_bp; int newpage; /* If prev_bp set, indicates a new overflow page. */ { - register BUFHEAD *bp; - register u_int is_disk_mask; - register int is_disk, segment_ndx; + BUFHEAD *bp; + u_int32_t is_disk_mask; + int is_disk, segment_ndx; SEGMENT segp; is_disk = 0; @@ -161,7 +166,7 @@ __get_buf(hashp, addr, prev_bp, newpage) return (NULL); if (!prev_bp) segp[segment_ndx] = - (BUFHEAD *)((u_int)bp | is_disk_mask); + (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask); } else { BUF_REMOVE(bp); MRU_INSERT(bp); @@ -178,15 +183,15 @@ __get_buf(hashp, addr, prev_bp, newpage) static BUFHEAD * newbuf(hashp, addr, prev_bp) HTAB *hashp; - u_int addr; + u_int32_t addr; BUFHEAD *prev_bp; { - register BUFHEAD *bp; /* The buffer we're going to use */ - register BUFHEAD *xbp; /* Temp pointer */ - register BUFHEAD *next_xbp; + BUFHEAD *bp; /* The buffer we're going to use */ + BUFHEAD *xbp; /* Temp pointer */ + BUFHEAD *next_xbp; SEGMENT segp; int segment_ndx; - u_short oaddr, *shortp; + u_int16_t oaddr, *shortp; oaddr = 0; bp = LRU; @@ -198,10 +203,16 @@ newbuf(hashp, addr, prev_bp) /* 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 { @@ -216,7 +227,7 @@ newbuf(hashp, addr, prev_bp) * Set oaddr before __put_page so that you get it * before bytes are swapped. */ - shortp = (u_short *)bp->page; + shortp = (u_int16_t *)bp->page; if (shortp[0]) oaddr = shortp[shortp[0] - 1]; if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page, @@ -259,7 +270,7 @@ newbuf(hashp, addr, prev_bp) (oaddr != xbp->addr)) break; - shortp = (u_short *)xbp->page; + shortp = (u_int16_t *)xbp->page; if (shortp[0]) /* set before __put_page */ oaddr = shortp[shortp[0] - 1]; diff --git a/db/hash/hash_func.c b/db/hash/hash_func.c index 2feb975..d84d82e 100644 --- a/db/hash/hash_func.c +++ b/db/hash/hash_func.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* +/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -58,6 +58,10 @@ * 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 #include @@ -66,13 +70,13 @@ #include "page.h" #include "extern.h" -static u_int32_t hash1 __P((const void *, size_t)); -static u_int32_t hash2 __P((const void *, size_t)); -static u_int32_t hash3 __P((const void *, size_t)); -static u_int32_t hash4 __P((const void *, size_t)); +static u_int32_t hash1(const void *, size_t) ; +static u_int32_t hash2(const void *, size_t) ; +static u_int32_t hash3(const void *, size_t) ; +static u_int32_t hash4(const void *, size_t); /* Global default hash function */ -u_int32_t (*__default_hash) __P((const void *, size_t)) = hash4; +u_int32_t (*__default_hash)(const void *, size_t) = hash4; /* * HASH FUNCTIONS @@ -89,10 +93,10 @@ u_int32_t (*__default_hash) __P((const void *, size_t)) = hash4; static u_int32_t hash1(keyarg, len) const void *keyarg; - register size_t len; + size_t len; { - register const u_char *key; - register u_int32_t h; + const u_char *key; + u_int32_t h; /* Convert string to integer */ for (key = keyarg, h = 0; len--;) @@ -111,9 +115,9 @@ hash2(keyarg, len) const void *keyarg; size_t len; { - register const u_char *e, *key; - register u_int32_t h; - register u_char c; + const u_char *e, *key; + u_int32_t h; + u_char c; key = keyarg; e = key + len; @@ -138,11 +142,11 @@ hash2(keyarg, len) static u_int32_t hash3(keyarg, len) const void *keyarg; - register size_t len; + size_t len; { - register const u_char *key; - register size_t loop; - register u_int32_t h; + const u_char *key; + size_t loop; + u_int32_t h; #define HASHC h = *key++ + 65599 * h @@ -186,11 +190,11 @@ hash3(keyarg, len) static u_int32_t hash4(keyarg, len) const void *keyarg; - register size_t len; + size_t len; { - register const u_char *key; - register size_t loop; - register u_int32_t h; + 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++; diff --git a/db/hash/hash_log2.c b/db/hash/hash_log2.c index b884e4e..6901c19 100644 --- a/db/hash/hash_log2.c +++ b/db/hash/hash_log2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,14 +58,20 @@ * 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 #include -u_int +#include + +u_int32_t __log2(num) - u_int num; + u_int32_t num; { - register u_int i, limit; + u_int32_t i, limit; limit = 1; for (i = 0; limit < num; limit = limit << 1, i++); diff --git a/db/hash/hash_page.c b/db/hash/hash_page.c index 58738e0..f045255 100644 --- a/db/hash/hash_page.c +++ b/db/hash/hash_page.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 /* * PACKAGE: hashing @@ -93,19 +97,19 @@ #include "page.h" #include "extern.h" -static u_long *fetch_bitmap __P((HTAB *, int)); -static u_long first_free __P((u_long)); -static int open_temp __P((HTAB *)); -static u_short overflow_page __P((HTAB *)); -static void putpair __P((char *, const DBT *, const DBT *)); -static void squeeze_key __P((u_short *, const DBT *, const DBT *)); +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 - __P((HTAB *, u_int, BUFHEAD *, BUFHEAD *, int, int)); +(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int); #define PAGE_INIT(P) { \ - ((u_short *)(P))[0] = 0; \ - ((u_short *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_short); \ - ((u_short *)(P))[2] = hashp->BSIZE; \ + ((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; \ } /* @@ -118,9 +122,9 @@ putpair(p, key, val) char *p; const DBT *key, *val; { - register u_short *bp, n, off; + u_int16_t *bp, n, off; - bp = (u_short *)p; + bp = (u_int16_t *)p; /* Enter the key first. */ n = bp[0]; @@ -136,7 +140,7 @@ putpair(p, key, val) /* Adjust page info. */ bp[0] = n; - bp[n + 1] = off - ((n + 3) * sizeof(u_short)); + bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t)); bp[n + 2] = off; } @@ -149,13 +153,13 @@ extern int __delpair(hashp, bufp, ndx) HTAB *hashp; BUFHEAD *bufp; - register int ndx; + int ndx; { - register u_short *bp, newoff; - register int n; - u_short pairlen; + u_int16_t *bp, newoff; + int n; + u_int16_t pairlen; - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; n = bp[0]; if (bp[ndx + 1] < REAL_KEY) @@ -168,9 +172,9 @@ __delpair(hashp, bufp, ndx) if (ndx != (n - 1)) { /* Hard Case -- need to shuffle keys */ - register int i; - register char *src = bufp->page + (int)OFFSET(bp); - register char *dst = src + (int)pairlen; + 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 */ @@ -186,7 +190,7 @@ __delpair(hashp, bufp, ndx) } /* Finally adjust the page data */ bp[n] = OFFSET(bp) + pairlen; - bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_short); + bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t); bp[0] = n - 2; hashp->NKEYS--; @@ -201,18 +205,18 @@ __delpair(hashp, bufp, ndx) extern int __split_page(hashp, obucket, nbucket) HTAB *hashp; - u_int obucket, nbucket; + u_int32_t obucket, nbucket; { - register BUFHEAD *new_bufp, *old_bufp; - register u_short *ino; - register char *np; + BUFHEAD *new_bufp, *old_bufp; + u_int16_t *ino; + char *np; DBT key, val; int n, ndx, retval; - u_short copyto, diff, off, moved; + u_int16_t copyto, diff, off, moved; char *op; - copyto = (u_short)hashp->BSIZE; - off = (u_short)hashp->BSIZE; + 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); @@ -223,7 +227,7 @@ __split_page(hashp, obucket, nbucket) old_bufp->flags |= (BUF_MOD | BUF_PIN); new_bufp->flags |= (BUF_MOD | BUF_PIN); - ino = (u_short *)(op = old_bufp->page); + ino = (u_int16_t *)(op = old_bufp->page); np = new_bufp->page; moved = 0; @@ -265,13 +269,13 @@ __split_page(hashp, obucket, nbucket) /* Now clean up the page */ ino[0] -= moved; - FREESPACE(ino) = copyto - sizeof(u_short) * (ino[0] + 3); + FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3); OFFSET(ino) = copyto; #ifdef DEBUG3 (void)fprintf(stderr, "split %d/%d\n", - ((u_short *)np)[0] / 2, - ((u_short *)op)[0] / 2); + ((u_int16_t *)np)[0] / 2, + ((u_int16_t *)op)[0] / 2); #endif /* unpin both pages */ old_bufp->flags &= ~BUF_PIN; @@ -297,28 +301,28 @@ __split_page(hashp, obucket, nbucket) static int ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) HTAB *hashp; - u_int obucket; /* Same as __split_page. */ + 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. */ + int moved; /* Number of pairs moved to new page. */ { - register BUFHEAD *bufp; /* Buffer header for ino */ - register u_short *ino; /* Page keys come off of */ - register u_short *np; /* New page */ - register u_short *op; /* Page keys go on to if they aren't moving */ + BUFHEAD *bufp; /* Buffer header for ino */ + u_int16_t *ino; /* Page keys come off of */ + u_int16_t *np; /* New page */ + u_int16_t *op; /* Page keys go on to if they aren't moving */ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */ DBT key, val; SPLIT_RETURN ret; - u_short n, off, ov_addr, scopyto; + u_int16_t n, off, ov_addr, scopyto; char *cino; /* Character value of ino */ bufp = old_bufp; - ino = (u_short *)old_bufp->page; - np = (u_short *)new_bufp->page; - op = (u_short *)old_bufp->page; + 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_short)copyto; /* ANSI */ + scopyto = (u_int16_t)copyto; /* ANSI */ n = ino[0] - 1; while (n < ino[0]) { @@ -329,16 +333,16 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) old_bufp = ret.oldp; if (!old_bufp) return (-1); - op = (u_short *)old_bufp->page; + op = (u_int16_t *)old_bufp->page; new_bufp = ret.newp; if (!new_bufp) return (-1); - np = (u_short *)new_bufp->page; + np = (u_int16_t *)new_bufp->page; bufp = ret.nextp; if (!bufp) return (0); cino = (char *)bufp->page; - ino = (u_short *)cino; + ino = (u_int16_t *)cino; last_bfp = ret.nextp; } else if (ino[n + 1] == OVFLPAGE) { ov_addr = ino[n]; @@ -348,14 +352,14 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) */ ino[0] -= (moved + 2); FREESPACE(ino) = - scopyto - sizeof(u_short) * (ino[0] + 3); + 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_short *)bufp->page; + ino = (u_int16_t *)bufp->page; n = 1; scopyto = hashp->BSIZE; moved = 0; @@ -383,7 +387,7 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) __add_ovflpage(hashp, old_bufp); if (!old_bufp) return (-1); - op = (u_short *)old_bufp->page; + op = (u_int16_t *)old_bufp->page; putpair((char *)op, &key, &val); } old_bufp->flags |= BUF_MOD; @@ -396,7 +400,7 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) __add_ovflpage(hashp, new_bufp); if (!new_bufp) return (-1); - np = (u_short *)new_bufp->page; + np = (u_int16_t *)new_bufp->page; putpair((char *)np, &key, &val); } new_bufp->flags |= BUF_MOD; @@ -421,10 +425,10 @@ __addel(hashp, bufp, key, val) BUFHEAD *bufp; const DBT *key, *val; { - register u_short *bp, *sop; + u_int16_t *bp, *sop; int do_expand; - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; do_expand = 0; while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY)) /* Exception case */ @@ -436,7 +440,7 @@ __addel(hashp, bufp, key, val) bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; } else /* Try to squeeze key on this page */ if (FREESPACE(bp) > PAIRSIZE(key, val)) { @@ -446,7 +450,7 @@ __addel(hashp, bufp, key, val) bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); - bp = (u_short *)bufp->page; + bp = (u_int16_t *)bufp->page; } if (PAIRFITS(bp, key, val)) @@ -456,7 +460,7 @@ __addel(hashp, bufp, key, val) bufp = __add_ovflpage(hashp, bufp); if (!bufp) return (-1); - sop = (u_short *)bufp->page; + sop = (u_int16_t *)bufp->page; if (PAIRFITS(sop, key, val)) putpair((char *)sop, key, val); @@ -487,12 +491,12 @@ __add_ovflpage(hashp, bufp) HTAB *hashp; BUFHEAD *bufp; { - register u_short *sp; - u_short ndx, ovfl_num; + u_int16_t *sp; + u_int16_t ndx, ovfl_num; #ifdef DEBUG1 int tmp1, tmp2; #endif - sp = (u_short *)bufp->page; + sp = (u_int16_t *)bufp->page; /* Check if we are dynamically determining the fill factor */ if (hashp->FFACTOR == DEF_FFACTOR) { @@ -539,12 +543,12 @@ extern int __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) HTAB *hashp; char *p; - u_int bucket; + u_int32_t bucket; int is_bucket, is_disk, is_bitmap; { - register int fd, page, size; + int fd, page, size; int rsize; - u_short *bp; + u_int16_t *bp; fd = hashp->fp; size = hashp->BSIZE; @@ -560,7 +564,7 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || ((rsize = read(fd, p, size)) == -1)) return (-1); - bp = (u_short *)p; + bp = (u_int16_t *)p; if (!rsize) bp[0] = 0; /* We hit the EOF, so initialize a new page */ else @@ -572,12 +576,12 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap) PAGE_INIT(p); } else if (hashp->LORDER != BYTE_ORDER) { - register int i, max; + int i, max; if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ for (i = 0; i < max; i++) - M_32_SWAP(((long *)p)[i]); + M_32_SWAP(((int *)p)[i]); } else { M_16_SWAP(bp[0]); max = bp[0] + 2; @@ -599,10 +603,10 @@ extern int __put_page(hashp, p, bucket, is_bucket, is_bitmap) HTAB *hashp; char *p; - u_int bucket; + u_int32_t bucket; int is_bucket, is_bitmap; { - register int fd, page, size; + int fd, page, size; int wsize; size = hashp->BSIZE; @@ -611,17 +615,17 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) fd = hashp->fp; if (hashp->LORDER != BYTE_ORDER) { - register int i; - register int max; + int i; + int max; if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ for (i = 0; i < max; i++) - M_32_SWAP(((long *)p)[i]); + M_32_SWAP(((int *)p)[i]); } else { - max = ((u_short *)p)[0] + 2; + max = ((u_int16_t *)p)[0] + 2; for (i = 0; i <= max; i++) - M_16_SWAP(((u_short *)p)[i]); + M_16_SWAP(((u_int16_t *)p)[i]); } } if (is_bucket) @@ -645,14 +649,14 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap) * once they are read in. */ extern int -__init_bitmap(hashp, pnum, nbits, ndx) +__ibitmap(hashp, pnum, nbits, ndx) HTAB *hashp; int pnum, nbits, ndx; { - u_long *ip; + u_int32_t *ip; int clearbytes, clearints; - if ((ip = (u_long *)malloc(hashp->BSIZE)) == NULL) + if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) return (1); hashp->nmaps++; clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1; @@ -662,16 +666,16 @@ __init_bitmap(hashp, pnum, nbits, ndx) hashp->BSIZE - clearbytes); ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK); SETBIT(ip, 0); - hashp->BITMAPS[ndx] = (u_short)pnum; + hashp->BITMAPS[ndx] = (u_int16_t)pnum; hashp->mapp[ndx] = ip; return (0); } -static u_long +static u_int32_t first_free(map) - u_long map; + u_int32_t map; { - register u_long i, mask; + u_int32_t i, mask; mask = 0x1; for (i = 0; i < BITS_PER_MAP; i++) { @@ -682,13 +686,13 @@ first_free(map) return (i); } -static u_short +static u_int16_t overflow_page(hashp) HTAB *hashp; { - register u_long *freep; - register int max_free, offset, splitnum; - u_short addr; + 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; @@ -702,14 +706,14 @@ overflow_page(hashp) /* 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_long *)hashp->mapp[i]) && + if (!(freep = (u_int32_t *)hashp->mapp[i]) && !(freep = fetch_bitmap(hashp, i))) - return (NULL); + 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); @@ -734,7 +738,7 @@ overflow_page(hashp) if (offset > SPLITMASK) { if (++splitnum >= NCACHED) { (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); - return (NULL); + return (0); } hashp->OVFL_POINT = splitnum; hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; @@ -747,7 +751,7 @@ overflow_page(hashp) free_page++; if (free_page >= NCACHED) { (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); - return (NULL); + return (0); } /* * This is tricky. The 1 indicates that you want the new page @@ -760,9 +764,9 @@ overflow_page(hashp) * don't have to if we tell init_bitmap not to leave it clear * in the first place. */ - if (__init_bitmap(hashp, (int)OADDR_OF(splitnum, offset), - 1, free_page)) - return (NULL); + if (__ibitmap(hashp, + (int)OADDR_OF(splitnum, offset), 1, free_page)) + return (0); hashp->SPARES[splitnum]++; #ifdef DEBUG2 free_bit = 2; @@ -772,7 +776,7 @@ overflow_page(hashp) if (++splitnum >= NCACHED) { (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); - return (NULL); + return (0); } hashp->OVFL_POINT = splitnum; hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; @@ -816,7 +820,7 @@ found: for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++); offset = (i ? bit - hashp->SPARES[i - 1] : bit); if (offset >= SPLITMASK) - return (NULL); /* Out of overflow pages */ + 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", @@ -835,16 +839,16 @@ __free_ovflpage(hashp, obufp) HTAB *hashp; BUFHEAD *obufp; { - register u_short addr; - u_long *freep; + u_int16_t addr; + u_int32_t *freep; int bit_address, free_page, free_bit; - u_short ndx; + u_int16_t ndx; addr = obufp->addr; #ifdef DEBUG1 (void)fprintf(stderr, "Freeing %d\n", addr); #endif - ndx = (((u_short)addr) >> SPLITSHIFT); + ndx = (((u_int16_t)addr) >> SPLITSHIFT); bit_address = (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1; if (bit_address < hashp->LAST_FREED) @@ -900,11 +904,11 @@ open_temp(hashp) */ static void squeeze_key(sp, key, val) - u_short *sp; + u_int16_t *sp; const DBT *key, *val; { - register char *p; - u_short free_space, n, off, pageno; + char *p; + u_int16_t free_space, n, off, pageno; p = (char *)sp; n = sp[0]; @@ -925,14 +929,14 @@ squeeze_key(sp, key, val) OFFSET(sp) = off; } -static u_long * +static u_int32_t * fetch_bitmap(hashp, ndx) HTAB *hashp; int ndx; { if (ndx >= hashp->nmaps) return (NULL); - if ((hashp->mapp[ndx] = (u_long *)malloc(hashp->BSIZE)) == 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)) { diff --git a/db/hash/ndbm.c b/db/hash/ndbm.c index a77d972..774bf0d 100644 --- a/db/hash/ndbm.c +++ b/db/hash/ndbm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* +/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -58,6 +58,10 @@ * 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 /* * This package provides a dbm compatible interface to the new hashing @@ -66,10 +70,11 @@ #include -#include #include #include +#include +#include #include "hash.h" /* @@ -88,9 +93,14 @@ dbm_open(file, flags, mode) info.bsize = 4096; info.ffactor = 40; info.nelem = 1; - info.cachesize = NULL; + 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)); @@ -113,15 +123,20 @@ dbm_fetch(db, key) DBM *db; datum key; { - datum retval; + datum retdata; int status; + DBT dbtkey, dbtretdata; - status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0); + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + status = (db->get)(db, &dbtkey, &dbtretdata, 0); if (status) { - retval.dptr = NULL; - retval.dsize = 0; + dbtretdata.data = NULL; + dbtretdata.size = 0; } - return (retval); + retdata.dptr = dbtretdata.data; + retdata.dsize = dbtretdata.size; + return (retdata); } /* @@ -134,11 +149,14 @@ dbm_firstkey(db) DBM *db; { int status; - datum retdata, retkey; + datum retkey; + DBT dbtretkey, dbtretdata; - status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST); + status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST); if (status) - retkey.dptr = NULL; + dbtretkey.data = NULL; + retkey.dptr = dbtretkey.data; + retkey.dsize = dbtretkey.size; return (retkey); } @@ -152,13 +170,17 @@ dbm_nextkey(db) DBM *db; { int status; - datum retdata, retkey; + datum retkey; + DBT dbtretkey, dbtretdata; - status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT); + status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT); if (status) - retkey.dptr = NULL; + dbtretkey.data = NULL; + retkey.dptr = dbtretkey.data; + retkey.dsize = dbtretkey.size; return (retkey); } + /* * Returns: * 0 on success @@ -170,8 +192,11 @@ dbm_delete(db, key) datum key; { int status; + DBT dbtkey; - status = (db->del)(db, (DBT *)&key, 0); + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + status = (db->del)(db, &dbtkey, 0); if (status) return (-1); else @@ -185,12 +210,18 @@ dbm_delete(db, key) * 1 if DBM_INSERT and entry exists */ extern int -dbm_store(db, key, content, flags) +dbm_store(db, key, data, flags) DBM *db; - datum key, content; + datum key, data; int flags; { - return ((db->put)(db, (DBT *)&key, (DBT *)&content, + 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)); } diff --git a/db/hash/page.h b/db/hash/page.h index 3c7ae3a..79d0939 100644 --- a/db/hash/page.h +++ b/db/hash/page.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -56,6 +56,9 @@ * LIABILITY, OR TORT (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 $ */ /* @@ -95,20 +98,20 @@ * You might as well do this up front. */ -#define PAIRSIZE(K,D) (2*sizeof(u_short) + (K)->size + (D)->size) -#define BIGOVERHEAD (4*sizeof(u_short)) -#define KEYSIZE(K) (4*sizeof(u_short) + (K)->size); -#define OVFLSIZE (2*sizeof(u_short)) +#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_short)) +#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t)) typedef struct { BUFHEAD *newp; BUFHEAD *oldp; BUFHEAD *nextp; - u_short next_addr; + u_int16_t next_addr; } SPLIT_RETURN; diff --git a/db/mpool/mpool.c b/db/mpool/mpool.c index b10400b..50eeed7 100644 --- a/db/mpool/mpool.c +++ b/db/mpool/mpool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -55,8 +55,13 @@ * 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 #include +#include #include #include @@ -66,31 +71,21 @@ #include #include + #define __MPOOLINTERFACE_PRIVATE -#include "mpool.h" +#include -static BKT *mpool_bkt __P((MPOOL *)); -static BKT *mpool_look __P((MPOOL *, pgno_t)); -static int mpool_write __P((MPOOL *, BKT *)); -#ifdef DEBUG -static void __mpoolerr __P((const char *fmt, ...)); -#endif +static BKT *mpool_bkt(MPOOL *); +static BKT *mpool_look(MPOOL *, pgno_t); +static int mpool_write(MPOOL *, BKT *); /* - * MPOOL_OPEN -- initialize a memory pool. - * - * Parameters: - * key: Shared buffer key. - * fd: File descriptor. - * pagesize: File page size. - * maxcache: Max number of cached pages. - * - * Returns: - * MPOOL pointer, NULL on error. + * mpool_open -- + * Initialize a memory pool. */ MPOOL * mpool_open(key, fd, pagesize, maxcache) - DBT *key; + void *key; int fd; pgno_t pagesize, maxcache; { @@ -98,55 +93,41 @@ mpool_open(key, fd, pagesize, maxcache) 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); - /* XXX - * We should only set st_size to 0 for pipes -- 4.4BSD has the fix so - * that stat(2) returns true for ISSOCK on pipes. Until then, this is - * fairly close. - */ if (!S_ISREG(sb.st_mode)) { errno = ESPIPE; return (NULL); } - if ((mp = (MPOOL *)malloc(sizeof(MPOOL))) == NULL) + /* Allocate and initialize the MPOOL cookie. */ + if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL) return (NULL); - mp->free.cnext = mp->free.cprev = (BKT *)&mp->free; - mp->lru.cnext = mp->lru.cprev = (BKT *)&mp->lru; + TAILQ_INIT(&mp->lqh); for (entry = 0; entry < HASHSIZE; ++entry) - mp->hashtable[entry].hnext = mp->hashtable[entry].hprev = - mp->hashtable[entry].cnext = mp->hashtable[entry].cprev = - (BKT *)&mp->hashtable[entry]; - mp->curcache = 0; + TAILQ_INIT(&mp->hqh[entry]); mp->maxcache = maxcache; - mp->pagesize = pagesize; mp->npages = sb.st_size / pagesize; + mp->pagesize = pagesize; mp->fd = fd; - mp->pgcookie = NULL; - mp->pgin = mp->pgout = NULL; - -#ifdef STATISTICS - mp->cachehit = mp->cachemiss = mp->pagealloc = mp->pageflush = - mp->pageget = mp->pagenew = mp->pageput = mp->pageread = - mp->pagewrite = 0; -#endif return (mp); } /* - * MPOOL_FILTER -- initialize input/output filters. - * - * Parameters: - * pgin: Page in conversion routine. - * pgout: Page out conversion routine. - * pgcookie: Cookie for page in/out routines. + * mpool_filter -- + * Initialize input/output filters. */ void mpool_filter(mp, pgin, pgout, pgcookie) MPOOL *mp; - void (*pgin) __P((void *, pgno_t, void *)); - void (*pgout) __P((void *, pgno_t, void *)); + void (*pgin)(void *, pgno_t, void *); + void (*pgout)(void *, pgno_t, void *); void *pgcookie; { mp->pgin = pgin; @@ -155,124 +136,128 @@ mpool_filter(mp, pgin, pgout, pgcookie) } /* - * MPOOL_NEW -- get a new page - * - * Parameters: - * mp: mpool cookie - * pgnoadddr: place to store new page number - * Returns: - * RET_ERROR, RET_SUCCESS + * mpool_new -- + * Get a new page of memory. */ void * mpool_new(mp, pgnoaddr) MPOOL *mp; pgno_t *pgnoaddr; { - BKT *b; - BKTHDR *hp; + 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 hash and lru chains and return. + * 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 ((b = mpool_bkt(mp)) == NULL) + if ((bp = mpool_bkt(mp)) == NULL) return (NULL); - *pgnoaddr = b->pgno = mp->npages++; - b->flags = MPOOL_PINNED; - inshash(b, b->pgno); - inschain(b, &mp->lru); - return (b->page); + *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 from the pool - * - * Parameters: - * mp: mpool cookie - * pgno: page number - * flags: not used - * - * Returns: - * RET_ERROR, RET_SUCCESS + * mpool_get + * Get a page. */ void * mpool_get(mp, pgno, flags) MPOOL *mp; pgno_t pgno; - u_int flags; /* XXX not used? */ + u_int flags; /* XXX not used? */ { - BKT *b; - BKTHDR *hp; + struct _hqh *head; + BKT *bp; off_t off; int nr; - /* - * If asking for a specific page that is already in the cache, find - * it and return it. - */ - if (b = mpool_look(mp, pgno)) { + /* Check for attempt to retrieve a non-existent page. */ + if (pgno >= mp->npages) { + errno = EINVAL; + return (NULL); + } + #ifdef STATISTICS - ++mp->pageget; + ++mp->pageget; #endif + + /* Check for a page that is cached. */ + if ((bp = mpool_look(mp, pgno)) != NULL) { #ifdef DEBUG - if (b->flags & MPOOL_PINNED) - __mpoolerr("mpool_get: page %d already pinned", - b->pgno); + if (bp->flags & MPOOL_PINNED) { + (void)fprintf(stderr, + "mpool_get: page %d already pinned\n", bp->pgno); + abort(); + } #endif - rmchain(b); - inschain(b, &mp->lru); - b->flags |= MPOOL_PINNED; - return (b->page); - } - - /* Not allowed to retrieve a non-existent page. */ - if (pgno >= mp->npages) { - errno = EINVAL; - return (NULL); + /* + * 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 ((b = mpool_bkt(mp)) == NULL) + if ((bp = mpool_bkt(mp)) == NULL) return (NULL); - b->pgno = pgno; - b->flags = MPOOL_PINNED; + /* Read in the contents. */ #ifdef STATISTICS ++mp->pageread; #endif - /* Read in the contents. */ off = mp->pagesize * pgno; if (lseek(mp->fd, off, SEEK_SET) != off) return (NULL); - if ((nr = read(mp->fd, b->page, mp->pagesize)) != mp->pagesize) { + if ((nr = read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) { if (nr >= 0) errno = EFTYPE; return (NULL); } - if (mp->pgin) - (mp->pgin)(mp->pgcookie, b->pgno, b->page); - inshash(b, b->pgno); - inschain(b, &mp->lru); -#ifdef STATISTICS - ++mp->pageget; -#endif - return (b->page); + /* 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 to the pool - * - * Parameters: - * mp: mpool cookie - * page: page pointer - * pgno: page number - * - * Returns: - * RET_ERROR, RET_SUCCESS + * mpool_put + * Return a page. */ int mpool_put(mp, page, flags) @@ -280,193 +265,171 @@ mpool_put(mp, page, flags) void *page; u_int flags; { - BKT *baddr; -#ifdef DEBUG - BKT *b; -#endif + BKT *bp; #ifdef STATISTICS ++mp->pageput; #endif - baddr = (BKT *)((char *)page - sizeof(BKT)); + bp = (BKT *)((char *)page - sizeof(BKT)); #ifdef DEBUG - if (!(baddr->flags & MPOOL_PINNED)) - __mpoolerr("mpool_put: page %d not pinned", b->pgno); - for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) { - if (b == (BKT *)&mp->lru) - __mpoolerr("mpool_put: %0x: bad address", baddr); - if (b == baddr) - break; + if (!(bp->flags & MPOOL_PINNED)) { + (void)fprintf(stderr, + "mpool_put: page %d not pinned\n", bp->pgno); + abort(); } #endif - baddr->flags &= ~MPOOL_PINNED; - baddr->flags |= flags & MPOOL_DIRTY; + bp->flags &= ~MPOOL_PINNED; + bp->flags |= flags & MPOOL_DIRTY; return (RET_SUCCESS); } /* - * MPOOL_CLOSE -- close the buffer pool - * - * Parameters: - * mp: mpool cookie - * - * Returns: - * RET_ERROR, RET_SUCCESS + * mpool_close + * Close the buffer pool. */ int mpool_close(mp) MPOOL *mp; { - BKT *b, *next; + BKT *bp; /* Free up any space allocated to the lru pages. */ - for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = next) { - next = b->cprev; - free(b); + 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 file to disk. - * - * Parameters: - * mp: mpool cookie - * - * Returns: - * RET_ERROR, RET_SUCCESS + * mpool_sync + * Sync the pool to disk. */ int mpool_sync(mp) MPOOL *mp; { - BKT *b; + BKT *bp; - for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = b->cprev) - if (b->flags & MPOOL_DIRTY && mpool_write(mp, b) == RET_ERROR) + /* Walk the lru chain, flushing any dirty pages to disk. */ + TAILQ_FOREACH(bp, &mp->lqh, q) + if (bp->flags & MPOOL_DIRTY && + mpool_write(mp, bp) == RET_ERROR) return (RET_ERROR); + + /* Sync the file descriptor. */ return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS); } /* - * MPOOL_BKT -- get/create a BKT from the cache - * - * Parameters: - * mp: mpool cookie - * - * Returns: - * NULL on failure and a pointer to the BKT on success + * mpool_bkt + * Get a page from the cache (or create one). */ static BKT * mpool_bkt(mp) MPOOL *mp; { - BKT *b; + 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 maxxed out, search 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. + * 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. */ - for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = b->cprev) - if (!(b->flags & MPOOL_PINNED)) { - if (b->flags & MPOOL_DIRTY && - mpool_write(mp, b) == RET_ERROR) + 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); - rmhash(b); - rmchain(b); #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 = b->page; - memset(b, 0xff, sizeof(BKT) + mp->pagesize); - b->page = spage; + { void *spage; + spage = bp->page; + memset(bp, 0xff, sizeof(BKT) + mp->pagesize); + bp->page = spage; } #endif - return (b); + return (bp); } -new: if ((b = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) +new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL) return (NULL); #ifdef STATISTICS ++mp->pagealloc; #endif -#ifdef DEBUG - memset(b, 0xff, sizeof(BKT) + mp->pagesize); +#if defined(DEBUG) || defined(PURIFY) + memset(bp, 0xff, sizeof(BKT) + mp->pagesize); #endif - b->page = (char *)b + sizeof(BKT); + bp->page = (char *)bp + sizeof(BKT); ++mp->curcache; - return (b); + return (bp); } /* - * MPOOL_WRITE -- sync a page to disk - * - * Parameters: - * mp: mpool cookie - * - * Returns: - * RET_ERROR, RET_SUCCESS + * mpool_write + * Write a page to disk. */ static int -mpool_write(mp, b) +mpool_write(mp, bp) MPOOL *mp; - BKT *b; + BKT *bp; { off_t off; - if (mp->pgout) - (mp->pgout)(mp->pgcookie, b->pgno, b->page); - #ifdef STATISTICS ++mp->pagewrite; #endif - off = mp->pagesize * b->pgno; + + /* Run through the user's filter. */ + if (mp->pgout) + (mp->pgout)(mp->pgcookie, bp->pgno, bp->page); + + off = mp->pagesize * bp->pgno; if (lseek(mp->fd, off, SEEK_SET) != off) return (RET_ERROR); - if (write(mp->fd, b->page, mp->pagesize) != mp->pagesize) + if (write(mp->fd, bp->page, mp->pagesize) != mp->pagesize) return (RET_ERROR); - b->flags &= ~MPOOL_DIRTY; + + bp->flags &= ~MPOOL_DIRTY; return (RET_SUCCESS); } /* - * MPOOL_LOOK -- lookup a page - * - * Parameters: - * mp: mpool cookie - * pgno: page number - * - * Returns: - * NULL on failure and a pointer to the BKT on success + * mpool_look + * Lookup a page in the cache. */ static BKT * mpool_look(mp, pgno) MPOOL *mp; pgno_t pgno; { - register BKT *b; - register BKTHDR *tb; + struct _hqh *head; + BKT *bp; - /* XXX - * If find the buffer, put it first on the hash chain so can - * find it again quickly. - */ - tb = &mp->hashtable[HASHKEY(pgno)]; - for (b = tb->hnext; b != (BKT *)tb; b = b->hnext) - if (b->pgno == pgno) { + head = &mp->hqh[HASHKEY(pgno)]; + TAILQ_FOREACH(bp, head, hq) + if (bp->pgno == pgno) { #ifdef STATISTICS ++mp->cachehit; #endif - return (b); + return (bp); } #ifdef STATISTICS ++mp->cachemiss; @@ -476,16 +439,14 @@ mpool_look(mp, pgno) #ifdef STATISTICS /* - * MPOOL_STAT -- cache statistics - * - * Parameters: - * mp: mpool cookie + * mpool_stat + * Print out cache statistics. */ void mpool_stat(mp) MPOOL *mp; { - BKT *b; + BKT *bp; int cnt; char *sep; @@ -507,11 +468,11 @@ mpool_stat(mp) sep = ""; cnt = 0; - for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) { - (void)fprintf(stderr, "%s%d", sep, b->pgno); - if (b->flags & MPOOL_DIRTY) + TAILQ_FOREACH(bp, &mp->lqh, q) { + (void)fprintf(stderr, "%s%d", sep, bp->pgno); + if (bp->flags & MPOOL_DIRTY) (void)fprintf(stderr, "d"); - if (b->flags & MPOOL_PINNED) + if (bp->flags & MPOOL_PINNED) (void)fprintf(stderr, "P"); if (++cnt == 10) { sep = "\n"; @@ -523,33 +484,3 @@ mpool_stat(mp) (void)fprintf(stderr, "\n"); } #endif - -#ifdef DEBUG -#if __STDC__ -#include -#else -#include -#endif - -static void -#if __STDC__ -__mpoolerr(const char *fmt, ...) -#else -__mpoolerr(fmt, va_alist) - char *fmt; - va_dcl -#endif -{ - va_list ap; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - abort(); - /* NOTREACHED */ -} -#endif diff --git a/db/recno/extern.h b/db/recno/extern.h index 16ee4f7..0d7d0e3 100644 --- a/db/recno/extern.h +++ b/db/recno/extern.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* +/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -53,24 +53,27 @@ * LIABILITY, OR TORT (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 "bt_extern.h" +#include "../btree/extern.h" -int __rec_close __P((DB *)); -int __rec_delete __P((const DB *, const DBT *, u_int)); -int __rec_dleaf __P((BTREE *, PAGE *, indx_t)); -int __rec_fd __P((const DB *)); -int __rec_fmap __P((BTREE *, recno_t)); -int __rec_fout __P((BTREE *)); -int __rec_fpipe __P((BTREE *, recno_t)); -int __rec_get __P((const DB *, const DBT *, DBT *, u_int)); -int __rec_iput __P((BTREE *, recno_t, const DBT *, u_int)); -int __rec_put __P((const DB *dbp, DBT *, const DBT *, u_int)); -int __rec_ret __P((BTREE *, EPG *, recno_t, DBT *, DBT *)); -EPG *__rec_search __P((BTREE *, recno_t, enum SRCHOP)); -int __rec_seq __P((const DB *, DBT *, DBT *, u_int)); -int __rec_sync __P((const DB *, u_int)); -int __rec_vmap __P((BTREE *, recno_t)); -int __rec_vout __P((BTREE *)); -int __rec_vpipe __P((BTREE *, recno_t)); +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_close.c b/db/recno/rec_close.c index 648b840..d457130 100644 --- a/db/recno/rec_close.c +++ b/db/recno/rec_close.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -55,11 +55,14 @@ * 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 #include #include - -#include +#include #include #include @@ -98,17 +101,17 @@ __rec_close(dbp) /* Committed to closing. */ status = RET_SUCCESS; - if (ISSET(t, R_MEMMAPPED) - && vm_deallocate(mach_task_self(), (vm_offset_t) t->bt_smap, t->bt_msize)) + if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) status = RET_ERROR; - if (!ISSET(t, R_INMEM)) - if (ISSET(t, R_CLOSEFP)) { + 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; @@ -148,39 +151,59 @@ __rec_sync(dbp, flags) if (flags == R_RECNOSYNC) return (__bt_sync(dbp, 0)); - if (ISSET(t, R_RDONLY | R_INMEM) || !ISSET(t, R_MODIFIED)) + if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED)) return (RET_SUCCESS); /* Read any remaining records into the tree. */ - if (!ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) + 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); - iov[1].iov_base = "\n"; - iov[1].iov_len = 1; - scursor = t->bt_rcursor; + /* Save the cursor. */ + scursor = t->bt_cursor.rcursor; key.size = sizeof(recno_t); key.data = &trec; - 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); - } - t->bt_rcursor = scursor; + 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); - CLR(t, R_MODIFIED); + F_CLR(t, R_MODIFIED); return (RET_SUCCESS); } diff --git a/db/recno/rec_delete.c b/db/recno/rec_delete.c index 416aa83..38c0f96 100644 --- a/db/recno/rec_delete.c +++ b/db/recno/rec_delete.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,6 +58,10 @@ * 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 #include @@ -68,7 +72,7 @@ #include #include "recno.h" -static int rec_rdelete __P((BTREE *, recno_t)); +static int rec_rdelete(BTREE *, recno_t); /* * __REC_DELETE -- Delete the item(s) referenced by a key. @@ -109,13 +113,13 @@ __rec_delete(dbp, key, flags) status = rec_rdelete(t, nrec); break; case R_CURSOR: - if (!ISSET(t, B_SEQINIT)) + if (!F_ISSET(&t->bt_cursor, CURS_INIT)) goto einval; if (t->bt_nrecs == 0) return (RET_SPECIAL); - status = rec_rdelete(t, t->bt_rcursor - 1); + status = rec_rdelete(t, t->bt_cursor.rcursor - 1); if (status == RET_SUCCESS) - --t->bt_rcursor; + --t->bt_cursor.rcursor; break; default: einval: errno = EINVAL; @@ -123,7 +127,7 @@ einval: errno = EINVAL; } if (status == RET_SUCCESS) - SET(t, B_MODIFIED | R_MODIFIED); + F_SET(t, B_MODIFIED | R_MODIFIED); return (status); } @@ -175,11 +179,11 @@ int __rec_dleaf(t, h, index) BTREE *t; PAGE *h; - indx_t index; + u_int32_t index; { - register RLEAF *rl; - register indx_t *ip, cnt, offset; - register size_t nbytes; + RLEAF *rl; + indx_t *ip, cnt, offset; + u_int32_t nbytes; char *from; void *to; diff --git a/db/recno/rec_get.c b/db/recno/rec_get.c index a6fc347..c749fa2 100644 --- a/db/recno/rec_get.c +++ b/db/recno/rec_get.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -55,6 +55,10 @@ * 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 #include @@ -111,7 +115,7 @@ __rec_get(dbp, key, data, flags) * original file. */ if (nrec > t->bt_nrecs) { - if (ISSET(t, R_EOF | R_INMEM)) + if (F_ISSET(t, R_EOF | R_INMEM)) return (RET_SPECIAL); if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS) return (status); @@ -122,7 +126,7 @@ __rec_get(dbp, key, data, flags) return (RET_ERROR); status = __rec_ret(t, e, 0, NULL, data); - if (ISSET(t, B_DB_LOCK)) + if (F_ISSET(t, B_DB_LOCK)) mpool_put(t->bt_mp, e->page, 0); else t->bt_pinned = e->page; @@ -148,31 +152,38 @@ __rec_fpipe(t, top) recno_t nrec; size_t len; int ch; - char *p; + u_char *p; - if (t->bt_dbufsz < t->bt_reclen) { - if ((t->bt_dbuf = - (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL) + 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_dbufsz = t->bt_reclen; + t->bt_rdata.size = t->bt_reclen; } - data.data = t->bt_dbuf; + data.data = t->bt_rdata.data; data.size = t->bt_reclen; - for (nrec = t->bt_nrecs; nrec < top; ++nrec) { + for (nrec = t->bt_nrecs; nrec < top;) { len = t->bt_reclen; - for (p = t->bt_dbuf;; *p++ = ch) - if ((ch = getc(t->bt_rfp)) == EOF || !len--) { - if (__rec_iput(t, nrec, &data, 0) - != RET_SUCCESS) + 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) { - SET(t, R_EOF); + F_SET(t, R_EOF); return (RET_SPECIAL); } return (RET_SUCCESS); @@ -195,17 +206,18 @@ __rec_vpipe(t, top) { DBT data; recno_t nrec; - indx_t len; + size_t len; size_t sz; int bval, ch; - char *p; + u_char *p; bval = t->bt_bval; for (nrec = t->bt_nrecs; nrec < top; ++nrec) { - for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) { + 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_dbuf; - data.size = p - t->bt_dbuf; + 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) @@ -214,19 +226,21 @@ __rec_vpipe(t, top) break; } if (sz == 0) { - len = p - t->bt_dbuf; - t->bt_dbufsz += (sz = 256); - if ((t->bt_dbuf = (char *)realloc(t->bt_dbuf, - t->bt_dbufsz)) == NULL) + 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 = t->bt_dbuf + len; + p = (u_char *)t->bt_rdata.data + len; } } if (ch == EOF) break; } if (nrec < top) { - SET(t, R_EOF); + F_SET(t, R_EOF); return (RET_SPECIAL); } return (RET_SUCCESS); @@ -249,33 +263,36 @@ __rec_fmap(t, top) { DBT data; recno_t nrec; - caddr_t sp, ep; + u_char *sp, *ep, *p; size_t len; - char *p; - if (t->bt_dbufsz < t->bt_reclen) { - if ((t->bt_dbuf = - (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL) + 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_dbufsz = t->bt_reclen; + t->bt_rdata.size = t->bt_reclen; } - data.data = t->bt_dbuf; + data.data = t->bt_rdata.data; data.size = t->bt_reclen; - sp = t->bt_cmap; - ep = t->bt_emap; + sp = (u_char *)t->bt_cmap; + ep = (u_char *)t->bt_emap; for (nrec = t->bt_nrecs; nrec < top; ++nrec) { if (sp >= ep) { - SET(t, R_EOF); + F_SET(t, R_EOF); return (RET_SPECIAL); } len = t->bt_reclen; - for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); - memset(p, t->bt_bval, len); + 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 = sp; + t->bt_cmap = (caddr_t)sp; return (RET_SUCCESS); } @@ -295,25 +312,25 @@ __rec_vmap(t, top) recno_t top; { DBT data; - caddr_t sp, ep; + u_char *sp, *ep; recno_t nrec; int bval; - sp = t->bt_cmap; - ep = t->bt_emap; + 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) { - SET(t, R_EOF); + F_SET(t, R_EOF); return (RET_SPECIAL); } for (data.data = sp; sp < ep && *sp != bval; ++sp); - data.size = sp - (caddr_t)data.data; + data.size = sp - (u_char *)data.data; if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) return (RET_ERROR); ++sp; } - t->bt_cmap = sp; + t->bt_cmap = (caddr_t)sp; return (RET_SUCCESS); } diff --git a/db/recno/rec_open.c b/db/recno/rec_open.c index 7a74b27..680f9be 100644 --- a/db/recno/rec_open.c +++ b/db/recno/rec_open.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -58,13 +58,15 @@ * 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 #include +#include #include -#include -#include - #include #include #include @@ -121,7 +123,7 @@ __rec_open(fname, flags, mode, openinfo, dflags) t = dbp->internal; if (openinfo) { if (openinfo->flags & R_FIXEDLEN) { - SET(t, R_FIXLEN); + F_SET(t, R_FIXLEN); t->bt_reclen = openinfo->reclen; if (t->bt_reclen == 0) goto einval; @@ -130,12 +132,11 @@ __rec_open(fname, flags, mode, openinfo, dflags) } else t->bt_bval = '\n'; - SET(t, R_RECNO); + F_SET(t, R_RECNO); if (fname == NULL) - SET(t, R_EOF | R_INMEM); + F_SET(t, R_EOF | R_INMEM); else t->bt_rfd = rfd; - t->bt_rcursor = 0; if (fname != NULL) { /* @@ -147,20 +148,20 @@ __rec_open(fname, flags, mode, openinfo, dflags) if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) { switch (flags & O_ACCMODE) { case O_RDONLY: - SET(t, R_RDONLY); + F_SET(t, R_RDONLY); break; default: goto einval; } slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) goto err; - SET(t, R_CLOSEFP); + F_SET(t, R_CLOSEFP); t->bt_irec = - ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe; + F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe; } else { switch (flags & O_ACCMODE) { case O_RDONLY: - SET(t, R_RDONLY); + F_SET(t, R_RDONLY); break; case O_RDWR: break; @@ -180,21 +181,29 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) * fails if the file is too large. */ if (sb.st_size == 0) - SET(t, R_EOF); + 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 ( (map_fd(rfd, 0, (vm_offset_t *) - &t->bt_smap, TRUE, t->bt_msize) - != KERN_SUCCESS) - || (vm_protect(mach_task_self(), (vm_offset_t) - t->bt_smap, t->bt_msize, TRUE, - VM_PROT_READ) != KERN_SUCCESS) ) + 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 = ISSET(t, R_FIXLEN) ? + t->bt_irec = F_ISSET(t, R_FIXLEN) ? __rec_fmap : __rec_vmap; - SET(t, R_MEMMAPPED); + F_SET(t, R_MEMMAPPED); +#else + goto slow; +#endif } } } @@ -212,13 +221,14 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL) goto err; if ((h->flags & P_TYPE) == P_BLEAF) { - h->flags = h->flags & ~P_TYPE | P_RLEAF; + 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 && - !ISSET(t, R_EOF | R_INMEM) && + !F_ISSET(t, R_EOF | R_INMEM) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) goto err; return (dbp); @@ -248,7 +258,7 @@ __rec_fd(dbp) } /* In-memory database can't have a file descriptor. */ - if (ISSET(t, R_INMEM)) { + if (F_ISSET(t, R_INMEM)) { errno = ENOENT; return (-1); } diff --git a/db/recno/rec_put.c b/db/recno/rec_put.c index fa516c5..4d82104 100644 --- a/db/recno/rec_put.c +++ b/db/recno/rec_put.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -55,6 +55,10 @@ * 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 #include @@ -87,7 +91,7 @@ __rec_put(dbp, key, data, flags) u_int flags; { BTREE *t; - DBT tdata; + DBT fdata, tdata; recno_t nrec; int status; @@ -99,11 +103,37 @@ __rec_put(dbp, key, data, flags) 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 (!ISSET(t, B_SEQINIT)) + if (!F_ISSET(&t->bt_cursor, CURS_INIT)) goto einval; - nrec = t->bt_rcursor; + nrec = t->bt_cursor.rcursor; break; case R_SETCURSOR: if ((nrec = *(recno_t *)key->data) == 0) @@ -136,11 +166,11 @@ einval: errno = EINVAL; * already in the database. If skipping records, create empty ones. */ if (nrec > t->bt_nrecs) { - if (!ISSET(t, R_EOF | R_INMEM) && + 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 (ISSET(t, R_FIXLEN)) { + if (F_ISSET(t, R_FIXLEN)) { if ((tdata.data = (void *)malloc(t->bt_reclen)) == NULL) return (RET_ERROR); @@ -154,18 +184,24 @@ einval: errno = EINVAL; if (__rec_iput(t, t->bt_nrecs, &tdata, 0) != RET_SUCCESS) return (RET_ERROR); - if (ISSET(t, R_FIXLEN)) + if (F_ISSET(t, R_FIXLEN)) free(tdata.data); } } - if ((status = __rec_iput(t, nrec - 1, data, flags)) != RET_SUCCESS) + if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS) return (status); - if (flags == R_SETCURSOR) - t->bt_rcursor = nrec; + switch (flags) { + case R_IAFTER: + nrec++; + break; + case R_SETCURSOR: + t->bt_cursor.rcursor = nrec; + break; + } - SET(t, R_MODIFIED); + F_SET(t, R_MODIFIED); return (__rec_ret(t, NULL, nrec, key, NULL)); } @@ -192,7 +228,7 @@ __rec_iput(t, nrec, data, flags) PAGE *h; indx_t index, nxtindex; pgno_t pg; - size_t nbytes; + u_int32_t nbytes; int dflags, status; char *dest, db[NOVFLSIZE]; @@ -208,7 +244,7 @@ __rec_iput(t, nrec, data, flags) tdata.data = db; tdata.size = NOVFLSIZE; *(pgno_t *)db = pg; - *(size_t *)(db + sizeof(pgno_t)) = data->size; + *(u_int32_t *)(db + sizeof(pgno_t)) = data->size; dflags = P_BIGDATA; data = &tdata; } else @@ -267,7 +303,7 @@ __rec_iput(t, nrec, data, flags) WR_RLEAF(dest, data, dflags); ++t->bt_nrecs; - SET(t, B_MODIFIED); + F_SET(t, B_MODIFIED); mpool_put(t->bt_mp, h, MPOOL_DIRTY); return (RET_SUCCESS); diff --git a/db/recno/rec_search.c b/db/recno/rec_search.c index 5d97a70..b9d6f6c 100644 --- a/db/recno/rec_search.c +++ b/db/recno/rec_search.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* +/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -55,6 +55,10 @@ * 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 #include @@ -87,8 +91,8 @@ __rec_search(t, recno, op) recno_t recno; enum SRCHOP op; { - register indx_t index; - register PAGE *h; + indx_t index; + PAGE *h; EPGNO *parent; RINTERNAL *r; pgno_t pg; @@ -112,8 +116,7 @@ __rec_search(t, recno, op) total += r->nrecs; } - if (__bt_push(t, pg, index - 1) == RET_ERROR) - return (NULL); + BT_PUSH(t, pg, index - 1); pg = r->pgno; switch (op) { diff --git a/db/recno/rec_seq.c b/db/recno/rec_seq.c index b3ab8cd..2760be8 100644 --- a/db/recno/rec_seq.c +++ b/db/recno/rec_seq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1991, 1993 +/*- + * 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 @@ -55,7 +55,7 @@ * SUCH DAMAGE. */ - +#include #include #include @@ -103,8 +103,8 @@ __rec_seq(dbp, key, data, flags) goto einval; break; case R_NEXT: - if (ISSET(t, B_SEQINIT)) { - nrec = t->bt_rcursor + 1; + if (F_ISSET(&t->bt_cursor, CURS_INIT)) { + nrec = t->bt_cursor.rcursor + 1; break; } /* FALLTHROUGH */ @@ -112,14 +112,14 @@ __rec_seq(dbp, key, data, flags) nrec = 1; break; case R_PREV: - if (ISSET(t, B_SEQINIT)) { - if ((nrec = t->bt_rcursor - 1) == 0) + 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 (!ISSET(t, R_EOF | R_INMEM) && + if (!F_ISSET(t, R_EOF | R_INMEM) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) return (RET_ERROR); nrec = t->bt_nrecs; @@ -130,7 +130,7 @@ einval: errno = EINVAL; } if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) { - if (!ISSET(t, R_EOF | R_INMEM) && + 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) @@ -140,11 +140,11 @@ einval: errno = EINVAL; if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL) return (RET_ERROR); - SET(t, B_SEQINIT); - t->bt_rcursor = nrec; + F_SET(&t->bt_cursor, CURS_INIT); + t->bt_cursor.rcursor = nrec; status = __rec_ret(t, e, nrec, key, data); - if (ISSET(t, B_DB_LOCK)) + if (F_ISSET(t, B_DB_LOCK)) mpool_put(t->bt_mp, e->page, 0); else t->bt_pinned = e->page; diff --git a/db/recno/rec_utils.c b/db/recno/rec_utils.c index f0cfe45..80d95b6 100644 --- a/db/recno/rec_utils.c +++ b/db/recno/rec_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,8 +22,8 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 +/*- + * 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 @@ -55,6 +55,10 @@ * 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 #include @@ -66,11 +70,14 @@ #include "recno.h" /* - * __REC_RET -- Build return data as a result of search or scan. + * __rec_ret -- + * Build return data. * * Parameters: * t: tree - * d: LEAF to be returned to the user. + * e: key/data pair to be returned + * nrec: record number + * key: user's key structure * data: user's data structure * * Returns: @@ -83,53 +90,58 @@ __rec_ret(t, e, nrec, key, data) recno_t nrec; DBT *key, *data; { - register RLEAF *rl; - register void *p; + RLEAF *rl; + void *p; - if (data == NULL) - goto retkey; + if (key == NULL) + goto dataonly; - rl = GETRLEAF(e->page, e->index); + /* 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 always copy big data to make it contigous. Otherwise, we + * 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_dbuf, &t->bt_dbufsz)) + &data->size, &t->bt_rdata.data, &t->bt_rdata.size)) return (RET_ERROR); - data->data = t->bt_dbuf; - } else if (ISSET(t, B_DB_LOCK)) { + 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_dbufsz) { - if ((p = - (void *)realloc(t->bt_dbuf, rl->dsize + 1)) == NULL) + 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_dbuf = p; - t->bt_dbufsz = rl->dsize + 1; + t->bt_rdata.data = p; + t->bt_rdata.size = rl->dsize + 1; } - memmove(t->bt_dbuf, rl->bytes, rl->dsize); + memmove(t->bt_rdata.data, rl->bytes, rl->dsize); data->size = rl->dsize; - data->data = t->bt_dbuf; + data->data = t->bt_rdata.data; } else { data->size = rl->dsize; data->data = rl->bytes; } - -retkey: if (key == NULL) - return (RET_SUCCESS); - - /* We have to copy the key, it's not on the page. */ - if (sizeof(recno_t) > t->bt_kbufsz) { - if ((p = (void *)realloc(t->bt_kbuf, sizeof(recno_t))) == NULL) - return (RET_ERROR); - t->bt_kbuf = p; - t->bt_kbufsz = sizeof(recno_t); - } - memmove(t->bt_kbuf, &nrec, sizeof(recno_t)); - key->size = sizeof(recno_t); - key->data = t->bt_kbuf; return (RET_SUCCESS); } diff --git a/db/recno/recno.h b/db/recno/recno.h index 74bfdce..d0c0e62 100644 --- a/db/recno/recno.h +++ b/db/recno/recno.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* +/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -53,9 +53,12 @@ * LIABILITY, OR TORT (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 +#include "../btree/btree.h" #include "extern.h" diff --git a/fbsdcompat/_fbsd_compat_.h b/fbsdcompat/_fbsd_compat_.h new file mode 100644 index 0000000..b792a35 --- /dev/null +++ b/fbsdcompat/_fbsd_compat_.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 __FBSD_COMPAT__H_ +#define __FBSD_COMPAT__H_ + +#include + +#define OFF_MAX LLONG_MAX +#define OFF_MIN LLONG_MIN +#ifndef _BIG_ENDIAN +#define _BIG_ENDIAN BIG_ENDIAN +#endif /* _BIG_ENDIAN */ +#define _BYTE_ORDER BYTE_ORDER +#define _LITTLE_ENDIAN LITTLE_ENDIAN +#define __ct_rune_t ct_rune_t +#define __int32_t int32_t +#define __int64_t int64_t +#define __va_list _BSD_VA_LIST_ + +/* + * Do the opposite of FreeBSD namespace.h; that is, map the "hidden" names + * back to the real names. + */ + +/* + * ISO C (C90) section. Most names in libc aren't in ISO C, so they + * should be here. Most aren't here... + */ +#define _err err +#define _warn warn + +#define _accept accept +#define _bind bind +#define _close close +#define _connect connect +#define _creat creat +#define _dup dup +#define _dup2 dup2 +#define _execve execve +#define _fcntl fcntl +/*#define _flock flock */ +#define _flockfile flockfile +#define _ftrylockfile ftrylockfile +#define _fstat fstat +#define _fstatfs fstatfs +#define _fsync fsync +#define _funlockfile funlockfile +#define _getdirentries getdirentries +/* #define _getlogin getlogin */ +#define _getpeername getpeername +#define _getprogname getprogname +#define _getsockname getsockname +#define _getsockopt getsockopt +#define _ioctl ioctl +/* #define _kevent kevent */ +#define _listen listen +#define _nanosleep nanosleep +#define _open open +#define _pause pause +#define _poll poll +#define _pthread_cond_broadcast pthread_cond_broadcast +#define _pthread_cond_destroy pthread_cond_destroy +#define _pthread_cond_init pthread_cond_init +#define _pthread_cond_signal pthread_cond_signal +#define _pthread_cond_timedwait pthread_cond_timedwait +#define _pthread_cond_wait pthread_cond_wait +#define _pthread_exit pthread_exit +#define _pthread_getspecific pthread_getspecific +#define _pthread_key_create pthread_key_create +#define _pthread_key_delete pthread_key_delete +#define _pthread_main_np pthread_main_np +#define _pthread_mutex_destroy pthread_mutex_destroy +#define _pthread_mutex_init pthread_mutex_init +#define _pthread_mutex_lock pthread_mutex_lock +#define _pthread_mutex_trylock pthread_mutex_trylock +#define _pthread_mutex_unlock pthread_mutex_unlock +#define _pthread_mutexattr_destroy pthread_mutexattr_destroy +#define _pthread_mutexattr_init pthread_mutexattr_init +#define _pthread_mutexattr_settype pthread_mutexattr_settype +#define _pthread_once pthread_once +#define _pthread_rwlock_destroy pthread_rwlock_destroy +#define _pthread_rwlock_init pthread_rwlock_init +#define _pthread_rwlock_rdlock pthread_rwlock_rdlock +#define _pthread_rwlock_wrlock pthread_rwlock_wrlock +#define _pthread_rwlock_tryrdlock pthread_rwlock_tryrdlock +#define _pthread_rwlock_trywrlock pthread_rwlock_trywrlock +#define _pthread_rwlock_unlock pthread_rwlock_unlock +#define _pthread_self pthread_self +#define _pthread_setspecific pthread_setspecific +#define _pthread_sigmask pthread_sigmask +#define _read read +#define _readv readv +#define _recvfrom recvfrom +#define _recvmsg recvmsg +#define _select select +#define _sendmsg sendmsg +#define _sendto sendto +#define _setsockopt setsockopt +#define _sigaction sigaction +#define _sigprocmask sigprocmask +#define _sigsuspend sigsuspend +#define _sleep sleep +#define _socket socket +#define _socketpair socketpair +#define _system system +#define _tcdrain tcdrain +#define _wait wait +#define _wait4 wait4 +#define _waitpid waitpid +#define _write write +#define _writev writev + +#define __creat creat +#define __fmtcheck fmtcheck +#define __inet_addr inet_addr +#define __inet_aton inet_aton +#define __inet_lnaof inet_lnaof +#define __inet_makeaddr inet_makeaddr +#define __inet_net_ntop inet_net_ntop +#define __inet_net_pton inet_net_pton +#define __inet_neta inet_neta +#define __inet_netof inet_netof +#define __inet_network inet_network +#define __inet_nsap_addr inet_nsap_addr +#define __inet_nsap_ntoa inet_nsap_ntoa +#define __inet_ntoa inet_ntoa +#define __inet_ntop inet_ntop +#define __inet_pton inet_pton +#define __makecontext makecontext +#define __makecontext makecontext +#define __pause pause +#define __pselect pselect +#define __signalcontext signalcontext +#define __sleep sleep +#define __strtok_r strtok_r +#define __swapcontext swapcontext +#define __system system +#define __tcdrain tcdrain +#define __vfscanf vfscanf +#define __wait wait +#define __waitpid waitpid + +#define _GENERIC_DIRSIZ(dp) \ + ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) + +#endif /* __FBSD_COMPAT__H_ */ diff --git a/gen/raise.c b/fbsdcompat/_fpmath.h similarity index 71% rename from gen/raise.c rename to fbsdcompat/_fpmath.h index 379c4c7..cae427f 100644 --- a/gen/raise.c +++ b/fbsdcompat/_fpmath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,9 +22,9 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. +/*- + * Copyright (c) 2002, 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 @@ -34,18 +34,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) @@ -53,14 +46,24 @@ * LIABILITY, OR TORT (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: /repoman/r/ncvs/src/lib/libc/i386/_fpmath.h,v 1.2 2003/04/05 22:10:13 das Exp $ */ +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :32; + unsigned int exp :15; + unsigned int sign :1; + unsigned int junk :16; + } bits; +}; -#include -#include +#define mask_nbit_l(u) ((u).bits.manh &= 0x7fffffff) -raise(s) - int s; -{ - return(kill(getpid(), s)); -} +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/compat-43/creat.c b/fbsdcompat/fpmath.h similarity index 66% rename from compat-43/creat.c rename to fbsdcompat/fpmath.h index 6725668..3387d2f 100644 --- a/compat-43/creat.c +++ b/fbsdcompat/fpmath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,9 +22,10 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. +/*- + * Copyright (c) 2003 Mike Barcroft + * Copyright (c) 2002 David Schultz + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,18 +35,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) @@ -53,17 +47,41 @@ * LIABILITY, OR TORT (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: /repoman/r/ncvs/src/lib/libc/include/fpmath.h,v 1.1 2003/02/08 20:37:53 mike Exp $ */ -#include +#include +#include "_fpmath.h" + +union IEEEf2bits { + float f; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN + unsigned int man :23; + unsigned int exp :8; + unsigned int sign :1; +#else /* _BIG_ENDIAN */ + unsigned int sign :1; + unsigned int exp :8; + unsigned int man :23; +#endif + } bits; +}; -#if __STDC__ -int creat(const char *path, mode_t mode) -#else -int creat(path, mode) - char *path; - mode_t mode; +union IEEEd2bits { + double d; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else /* _BIG_ENDIAN */ + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; #endif -{ - return(open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)); -} + } bits; +}; diff --git a/stdio/local.h b/fbsdcompat/libc_private.h similarity index 52% rename from stdio/local.h rename to fbsdcompat/libc_private.h index 5be0041..af39a63 100644 --- a/stdio/local.h +++ b/fbsdcompat/libc_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,11 +23,8 @@ * @APPLE_LICENSE_HEADER_END@ */ /* - * 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) 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 @@ -39,13 +36,12 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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 THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * 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 @@ -56,55 +52,86 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/include/libc_private.h,v 1.8 2002/11/13 21:55:22 deischen Exp $ + * + * Private definitions for libc, libc_r and libpthread. + * */ -/* - * Information local to this implementation of stdio, - * in particular, macros and private variables. - */ +#ifndef _LIBC_PRIVATE_H_ +#define _LIBC_PRIVATE_H_ -extern int __sflush __P((FILE *)); -extern FILE *__sfp __P((void)); -extern int __srefill __P((FILE *)); -extern int __sread __P((void *, char *, int)); -extern int __swrite __P((void *, char const *, int)); -extern fpos_t __sseek __P((void *, fpos_t, int)); -extern int __sclose __P((void *)); -extern void __sinit __P((void)); -extern void _cleanup __P((void)); -extern void (*__cleanup) __P((void)); -extern void __smakebuf __P((FILE *)); -extern int __swhatbuf __P((FILE *, size_t *, int *)); -extern int _fwalk __P((int (*)(FILE *))); -extern int __swsetup __P((FILE *)); -extern int __sflags __P((const char *, int *)); +#ifdef __APPLE__ +#define __isthreaded __is_threaded +#endif // __APPLE__ -extern int __sdidinit; -extern void (*__cleanup) __P((void)); +/* + * This global flag is non-zero when a process has created one + * or more threads. It is used to avoid calling locking functions + * when they are not required. + */ +extern int __isthreaded; /* - * Return true iff the given FILE cannot be written now. + * File lock contention is difficult to diagnose without knowing + * where locks were set. Allow a debug library to be built which + * records the source file and line number of each lock call. */ -#define cantwrite(fp) \ - ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ - __swsetup(fp)) +#ifdef _FLOCK_DEBUG +#define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__) +#else +#define _FLOCKFILE(x) _flockfile(x) +#endif /* - * Test whether the given stdio file has an active ungetc buffer; - * release such a buffer, without restoring ordinary unread data. + * Macros for locking and unlocking FILEs. These test if the + * process is threaded to avoid locking when not required. */ -#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; \ -} +#define FLOCKFILE(fp) if (__isthreaded) _FLOCKFILE(fp) +#define FUNLOCKFILE(fp) if (__isthreaded) _funlockfile(fp) /* - * test for an fgetln() buffer. + * Indexes into the pthread jump table. + * + * Warning! If you change this type, you must also change the threads + * libraries that reference it (libc_r, libpthread). */ -#define HASLB(fp) ((fp)->_lb._base != NULL) -#define FREELB(fp) { \ - free((char *)(fp)->_lb._base); \ - (fp)->_lb._base = NULL; \ -} +typedef enum { + PJT_COND_BROADCAST, + PJT_COND_DESTROY, + PJT_COND_INIT, + PJT_COND_SIGNAL, + PJT_COND_WAIT, + PJT_GETSPECIFIC, + PJT_KEY_CREATE, + PJT_KEY_DELETE, + PJT_MAIN_NP, + PJT_MUTEX_DESTROY, + PJT_MUTEX_INIT, + PJT_MUTEX_LOCK, + PJT_MUTEX_TRYLOCK, + PJT_MUTEX_UNLOCK, + PJT_MUTEXATTR_DESTROY, + PJT_MUTEXATTR_INIT, + PJT_MUTEXATTR_SETTYPE, + PJT_ONCE, + PJT_RWLOCK_DESTROY, + PJT_RWLOCK_INIT, + PJT_RWLOCK_RDLOCK, + PJT_RWLOCK_TRYRDLOCK, + PJT_RWLOCK_TRYWRLOCK, + PJT_RWLOCK_UNLOCK, + PJT_RWLOCK_WRLOCK, + PJT_SELF, + PJT_SETSPECIFIC, + PJT_SIGMASK, + PJT_MAX +} pjt_index_t; + +typedef int (*pthread_func_t)(void); +typedef pthread_func_t pthread_func_entry_t[2]; + +extern pthread_func_entry_t __thr_jtable[]; + +#endif /* _LIBC_PRIVATE_H_ */ diff --git a/fbsdcompat/machine/atomic.h b/fbsdcompat/machine/atomic.h new file mode 100644 index 0000000..dc3ddf4 --- /dev/null +++ b/fbsdcompat/machine/atomic.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 left intentionally blank. + */ diff --git a/fbsdcompat/namespace.h b/fbsdcompat/namespace.h new file mode 100644 index 0000000..7e4fdf0 --- /dev/null +++ b/fbsdcompat/namespace.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 left intentionally blank + */ diff --git a/fbsdcompat/spinlock.h b/fbsdcompat/spinlock.h new file mode 100644 index 0000000..791d952 --- /dev/null +++ b/fbsdcompat/spinlock.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 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. + * + * $FreeBSD: src/lib/libc/include/spinlock.h,v 1.5 2002/03/21 22:47:52 obrien Exp $ + * + * Lock definitions used in both libc and libpthread. + * + */ + +#ifndef _SPINLOCK_H_ +#define _SPINLOCK_H_ +#ifdef __APPLE__ +#include + +typedef pthread_lock_t spinlock_t; + +#define _SPINLOCK_INITIALIZER LOCK_INITIALIZER + +#define _SPINLOCK(_lck) \ + do { \ + _DO_SPINLOCK_LOCK(_lck); \ + } while (0) + +#define _SPINUNLOCK(_lck) \ + do { \ + _DO_SPINLOCK_UNLOCK(_lck); \ + } while (0) + +#else /* ! __APPLE__ */ +#include +#include + +/* + * Lock structure with room for debugging information. + */ +typedef struct { + volatile long access_lock; + volatile long lock_owner; + volatile char *fname; + volatile int lineno; +} spinlock_t; + +#define _SPINLOCK_INITIALIZER { 0, 0, 0, 0 } + +#define _SPINUNLOCK(_lck) (_lck)->access_lock = 0 +#ifdef _LOCK_DEBUG +#define _SPINLOCK(_lck) _spinlock_debug(_lck, __FILE__, __LINE__) +#else +#define _SPINLOCK(_lck) _spinlock(_lck) +#endif + +/* + * Thread function prototype definitions: + */ +__BEGIN_DECLS +long _atomic_lock(volatile long *); +void _spinlock(spinlock_t *); +void _spinlock_debug(spinlock_t *, char *, int); +__END_DECLS + +#endif /* __APPLE__ */ + +#endif /* _SPINLOCK_H_ */ diff --git a/fbsdcompat/sys/cdefs.h b/fbsdcompat/sys/cdefs.h new file mode 100644 index 0000000..521fb6d --- /dev/null +++ b/fbsdcompat/sys/cdefs.h @@ -0,0 +1,495 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, 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. + * + * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 + * $FreeBSD: /repoman/r/ncvs/src/sys/sys/cdefs.h,v 1.68 2002/10/21 20:50:30 mike Exp $ + */ + +#ifndef _SYS_CDEFS_H_ +#define _SYS_CDEFS_H_ +//------------------------- Begin Added ---------------------------------- +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 1995 NeXT Computer, Inc. All rights reserved. */ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, 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. + * + * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 + */ + +#ifdef __APPLE__ +/* + * GCC1 and some versions of GCC2 declare dead (non-returning) and + * pure (no side effects) functions using "volatile" and "const"; + * unfortunately, these then cause warnings under "-ansi -pedantic". + * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of + * these work for GNU C++ (modulo a slight glitch in the C++ grammar + * in the distribution version of 2.5.5). + */ +#if defined(__MWERKS__) && (__MWERKS__ > 0x2400) + /* newer Metrowerks compilers support __attribute__() */ +#elif !defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define __dead __volatile +#define __pure __const +#endif +#endif + +/* Delete pseudo-keywords wherever they are not available or needed. */ +#ifndef __dead +#define __dead +#define __pure +#endif +#endif // __APPLE__ +//-------------------------- End Added ----------------------------------- + +#if defined(__cplusplus) +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif + +/* + * The __CONCAT macro is used to concatenate parts of symbol names, e.g. + * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. + * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI + * mode -- there must be no spaces between its arguments, and for nested + * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also + * concatenate double-quoted strings produced by the __STRING macro, but + * this only works with ANSI C. + * + * __XSTRING is like __STRING, but it expands any macros in its argument + * first. It is only available with ANSI C. + */ +#if defined(__STDC__) || defined(__cplusplus) +#define __P(protos) protos /* full-blown ANSI C */ +#define __CONCAT1(x,y) x ## y +#define __CONCAT(x,y) __CONCAT1(x,y) +#define __STRING(x) #x /* stringify without expanding x */ +#define __XSTRING(x) __STRING(x) /* expand x, then stringify */ + +#define __const const /* define reserved names to standard */ +#define __signed signed +#define __volatile volatile +#if defined(__cplusplus) +#define __inline inline /* convert to C++ keyword */ +#else +#ifndef __GNUC__ +#define __inline /* delete GCC keyword */ +#endif /* !__GNUC__ */ +#endif /* !__cplusplus */ + +#else /* !(__STDC__ || __cplusplus) */ +#define __P(protos) () /* traditional C preprocessor */ +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#ifndef __GNUC__ +#define __const /* delete pseudo-ANSI C keywords */ +#define __inline +#define __signed +#define __volatile +/* + * In non-ANSI C environments, new programs will want ANSI-only C keywords + * deleted from the program and old programs will want them left alone. + * When using a compiler other than gcc, programs using the ANSI C keywords + * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. + * When using "gcc -traditional", we assume that this is the intent; if + * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. + */ +#ifndef NO_ANSI_KEYWORDS +#define const /* delete ANSI C keywords */ +#define inline +#define signed +#define volatile +#endif /* !NO_ANSI_KEYWORDS */ +#endif /* !__GNUC__ */ +#endif /* !(__STDC__ || __cplusplus) */ + +/* + * Compiler-dependent macros to help declare dead (non-returning) and + * pure (no side effects) functions, and unused variables. They are + * null except for versions of gcc that are known to support the features + * properly (old versions of gcc-2 supported the dead and pure features + * in a different (wrong) way). If we do not provide an implementation + * for a given compiler, let the compile fail if it is told to use + * a feature that we cannot live without. + */ +#ifdef lint +#define __dead2 +#define __pure2 +#define __unused +#define __packed +#define __aligned(x) +#define __section(x) +#else +#if __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 5 +#define __dead2 +#define __pure2 +#define __unused +#endif +#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused +/* XXX Find out what to do for __packed, __aligned and __section */ +#endif +#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ == 3 +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused __attribute__((__unused__)) +#define __packed __attribute__((__packed__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#define __section(x) __attribute__((__section__(x))) +#endif +#endif + +/* XXX: should use `#if __STDC_VERSION__ < 199901'. */ +#if !(__GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3) +#define __func__ NULL +#endif + +#if __GNUC__ >= 2 && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901 +#define __LONG_LONG_SUPPORTED +#endif + +/* + * GCC 2.95 provides `__restrict' as an extension to C90 to support the + * C99-specific `restrict' type qualifier. We happen to use `__restrict' as + * a way to define the `restrict' type qualifier without disturbing older + * software that is unaware of C99 keywords. + */ +#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95) +#if __STDC_VERSION__ < 199901 +#define __restrict +#else +#define __restrict restrict +#endif +#endif + +/* + * We define this here since , , and + * require it. + */ +#define __offsetof(type, field) ((size_t)(&((type *)0)->field)) + +/* + * Compiler-dependent macros to declare that functions take printf-like + * or scanf-like arguments. They are null except for versions of gcc + * that are known to support the features properly (old versions of gcc-2 + * didn't permit keeping the keywords out of the application namespace). + */ +#if __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 7 +#define __printflike(fmtarg, firstvararg) +#define __scanflike(fmtarg, firstvararg) +#else +#define __printflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#define __scanflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) +#endif + +/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */ +#if __FreeBSD_cc_version >= 300001 && __FreeBSD_cc_version < 500003 +#define __printf0like(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf0__, fmtarg, firstvararg))) +#else +#define __printf0like(fmtarg, firstvararg) +#endif + +#ifdef __GNUC__ +#define __strong_reference(sym,aliassym) \ + extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))); +#ifdef __APPLE__ +#define __weak_reference(sym,alias) +#define __warn_references(sym,msg) +#else // ! __APPLE__ +#ifdef __STDC__ +#define __weak_reference(sym,alias) \ + __asm__(".weak " #alias); \ + __asm__(".equ " #alias ", " #sym) +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning." #sym); \ + __asm__(".asciz \"" msg "\""); \ + __asm__(".previous") +#else +#define __weak_reference(sym,alias) \ + __asm__(".weak alias"); \ + __asm__(".equ alias, sym") +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning.sym"); \ + __asm__(".asciz \"msg\""); \ + __asm__(".previous") +#endif /* __STDC__ */ +#endif // __APPLE__ +#endif /* __GNUC__ */ + +#ifdef __APPLE__ +#define __IDSTRING(name,string) \ + static const char name[] __attribute__((__unused__)) = string +#else // ! __APPLE__ +#ifdef __GNUC__ +#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"") +#else +/* + * This doesn't work in header files. But it may be better than nothing. + * The alternative is: #define __IDSTRING(name,string) [nothing] + */ +#define __IDSTRING(name,string) static const char name[] __unused = string +#endif +#endif // __APPLE__ + +/* + * Embed the rcs id of a source file in the resulting library. Note that in + * more recent ELF binutils, we use .ident allowing the ID to be stripped. + * Usage: + * __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/sys/cdefs.h,v 1.68 2002/10/21 20:50:30 mike Exp $"); + */ +#ifndef __FBSDID +#if !defined(lint) && !defined(STRIP_FBSDID) +#define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) +#else +#define __FBSDID(s) struct __hack +#endif +#endif + +#ifndef __RCSID +#ifndef NO__RCSID +#define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) +#else +#define __RCSID(s) +#endif +#endif + +#ifndef __RCSID_SOURCE +#ifndef NO__RCSID_SOURCE +#define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s) +#else +#define __RCSID_SOURCE(s) +#endif +#endif + +#ifndef __SCCSID +#ifndef NO__SCCSID +#define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s) +#else +#define __SCCSID(s) +#endif +#endif + +#ifndef __COPYRIGHT +#ifndef NO__COPYRIGHT +#define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s) +#else +#define __COPYRIGHT(s) +#endif +#endif + +#ifndef __DECONST +#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) +#endif + +#ifndef __DEVOLATILE +#define __DEVOLATILE(type, var) ((type)(uintptr_t)(volatile void *)(var)) +#endif + +#ifndef __DEQUALIFY +#define __DEQUALIFY(type, var) ((type)(uintptr_t)(const volatile void *)(var)) +#endif + +/*- + * The following definitions are an extension of the behavior originally + * implemented in , but with a different level of granularity. + * POSIX.1 requires that the macros we test be defined before any standard + * header file is included. + * + * Here's a quick run-down of the versions: + * defined(_POSIX_SOURCE) 1003.1-1988 + * _POSIX_C_SOURCE == 1 1003.1-1990 + * _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option + * _POSIX_C_SOURCE == 199309 1003.1b-1993 + * _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + * _POSIX_C_SOURCE == 200112 1003.1-2001 + * + * In addition, the X/Open Portability Guide, which is now the Single UNIX + * Specification, defines a feature-test macro which indicates the version of + * that specification, and which subsumes _POSIX_C_SOURCE. + * + * Our macros begin with two underscores to avoid namespace screwage. + */ + +/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */ +#if _POSIX_C_SOURCE == 1 +#undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */ +#define _POSIX_C_SOURCE 199009 +#endif + +/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */ +#if _POSIX_C_SOURCE == 2 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199209 +#endif + +/* Deal with various X/Open Portability Guides and Single UNIX Spec. */ +#ifdef _XOPEN_SOURCE +#if _XOPEN_SOURCE - 0 >= 600 +#define __XSI_VISIBLE 600 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112 +#elif _XOPEN_SOURCE - 0 >= 500 +#define __XSI_VISIBLE 500 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199506 +#endif +#endif + +/* + * Deal with all versions of POSIX. The ordering relative to the tests above is + * important. + */ +#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 198808 +#endif +#ifdef _POSIX_C_SOURCE +#if _POSIX_C_SOURCE >= 200112 +#define __POSIX_VISIBLE 200112 +#define __ISO_C_VISIBLE 1999 +#elif _POSIX_C_SOURCE >= 199506 +#define __POSIX_VISIBLE 199506 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199309 +#define __POSIX_VISIBLE 199309 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199209 +#define __POSIX_VISIBLE 199209 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199009 +#define __POSIX_VISIBLE 199009 +#define __ISO_C_VISIBLE 1990 +#else +#define __POSIX_VISIBLE 198808 +#define __ISO_C_VISIBLE 0 +#endif /* _POSIX_C_SOURCE */ +#else +/*- + * Deal with _ANSI_SOURCE: + * If it is defined, and no other compilation environment is explicitly + * requested, then define our internal feature-test macros to zero. This + * makes no difference to the preprocessor (undefined symbols in preprocessing + * expressions are defined to have value zero), but makes it more convenient for + * a test program to print out the values. + * + * If a program mistakenly defines _ANSI_SOURCE and some other macro such as + * _POSIX_C_SOURCE, we will assume that it wants the broader compilation + * environment (and in fact we will never get here). + */ +#if defined(_ANSI_SOURCE) /* Hide almost everything. */ +#define __POSIX_VISIBLE 0 +#define __XSI_VISIBLE 0 +#define __BSD_VISIBLE 0 +#define __ISO_C_VISIBLE 1990 +#elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */ +#define __POSIX_VISIBLE 0 +#define __XSI_VISIBLE 0 +#define __BSD_VISIBLE 0 +#define __ISO_C_VISIBLE 1999 +#else /* Default environment: show everything. */ +#define __POSIX_VISIBLE 200112 +#define __XSI_VISIBLE 600 +#define __BSD_VISIBLE 1 +#define __ISO_C_VISIBLE 1999 +#endif +#endif + +#endif /* !_SYS_CDEFS_H_ */ diff --git a/fbsdcompat/sys/endian.h b/fbsdcompat/sys/endian.h new file mode 100644 index 0000000..e9c8f51 --- /dev/null +++ b/fbsdcompat/sys/endian.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 _SYS_ENDIAN_H_ +#define _SYS_ENDIAN_H_ +#include +#endif /* _SYS_ENDIAN_H_ */ diff --git a/fbsdcompat/un-namespace.h b/fbsdcompat/un-namespace.h new file mode 100644 index 0000000..7e4fdf0 --- /dev/null +++ b/fbsdcompat/un-namespace.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 left intentionally blank + */ diff --git a/gdtoa/FreeBSD/_ldtoa.c b/gdtoa/FreeBSD/_ldtoa.c new file mode 100644 index 0000000..3560ebb --- /dev/null +++ b/gdtoa/FreeBSD/_ldtoa.c @@ -0,0 +1,97 @@ +/*- + * 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.1 2003/04/05 22:10:13 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 fpi = { + 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]; + + u.e = *ld; + *sign = u.bits.sign; + be = u.bits.exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1); + LDBL_TO_ARRAY32(u, bits); + + switch (fpclassify(u.e)) { + case FP_NORMAL: + kind = STRTOG_Normal; +#ifdef LDBL_IMPLICIT_NBIT + bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); +#endif /* LDBL_IMPLICIT_NBIT */ + break; + case FP_ZERO: + kind = STRTOG_Zero; + break; + case FP_SUBNORMAL: + kind = STRTOG_Denormal; + break; + case FP_INFINITE: + kind = STRTOG_Infinite; + break; + case FP_NAN: + kind = STRTOG_NaN; + break; + default: + abort(); + } + + ret = gdtoa(&fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve); + if (*decpt == -32768) + *decpt = INT_MAX; + return ret; +} diff --git a/gdtoa/FreeBSD/gdtoa-dmisc.c b/gdtoa/FreeBSD/gdtoa-dmisc.c new file mode 100644 index 0000000..14b5d7e --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-dmisc.c @@ -0,0 +1,222 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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/FreeBSD/gdtoa-dtoa.c b/gdtoa/FreeBSD/gdtoa-dtoa.c new file mode 100644 index 0000000..20e2405 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-dtoa.c @@ -0,0 +1,759 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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. 92-101]. + * + * 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/FreeBSD/gdtoa-gdtoa.c b/gdtoa/FreeBSD/gdtoa-gdtoa.c new file mode 100644 index 0000000..706c055 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-gdtoa.c @@ -0,0 +1,764 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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. 92-101]. + * + * 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; + 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/FreeBSD/gdtoa-gethex.c b/gdtoa/FreeBSD/gdtoa-gethex.c new file mode 100644 index 0000000..0f9ae33 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-gethex.c @@ -0,0 +1,247 @@ +/**************************************************************** + +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@acm.org + */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + int +#ifdef KR_headers +gethex(sp, fpi, exp, bp, sign) + CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; +#else +gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) +#endif +{ + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + int esign, havedig, irv, k, n, nbits, up; + ULong L, lostbits, *x; + Long e, e1; +#ifdef USE_LOCALE + char decimalpoint = *localeconv()->decimal_point; +#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; + if (!hexdig[*s]) { + if (*s == decimalpoint) { + decpt = ++s; + if (!hexdig[*s]) + goto ret0; + } + else { + ret0: + *sp = (char*)s; + return havedig ? STRTOG_Zero : STRTOG_NoNumber; + } + while(*s == '0') + s++; + havedig = 1; + if (!hexdig[*s]) + goto ret0; + s0 = s; + } + while(hexdig[*s]) + s++; + if (*s == decimalpoint && !decpt) { + decpt = ++s; + while(hexdig[*s]) + s++; + } + e = 0; + if (decpt) + e = -(((Long)(s-decpt)) << 2); + 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; + 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) { + if (*--s1 == decimalpoint) + continue; + 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); + 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); + 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 (b->wds > k + || (n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n) { + rshift(b,1); + if (++e > fpi->emax) + goto ovfl; + } + else if (irv == STRTOG_Denormal) { + k = nbits - 1; + if (x[k >> kshift] & 1 << (k & kmask)) + irv = STRTOG_Normal; + } + irv |= STRTOG_Inexhi; + } + else + irv |= STRTOG_Inexlo; + } + *bp = b; + *exp = e; + return irv; + } diff --git a/gdtoa/FreeBSD/gdtoa-gmisc.c b/gdtoa/FreeBSD/gdtoa-gmisc.c new file mode 100644 index 0000000..1607f4b --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-gmisc.c @@ -0,0 +1,92 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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/FreeBSD/gdtoa-hd_init.c b/gdtoa/FreeBSD/gdtoa-hd_init.c new file mode 100644 index 0000000..73afca1 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-hd_init.c @@ -0,0 +1,61 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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/FreeBSD/gdtoa-hexnan.c b/gdtoa/FreeBSD/gdtoa-hexnan.c new file mode 100644 index 0000000..7a7e03a --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-hexnan.c @@ -0,0 +1,137 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + 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 +{ + ULong c, h, *x, *x1, *xe; + 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; + 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; + } + return STRTOG_NaN; + } + havedig++; + if (++i > 8) { + if (x <= x0) + continue; + i = 1; + *--x = 0; + } + *x = (*x << 4) | h & 0xf; + } + 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); + } + else { + /* truncate high-order word if necessary */ + if ( (i = nbits & (ULbits-1)) !=0) + *xe &= ((ULong)0xffffffff) >> (ULbits - i); + } + for(x1 = xe;; --x1) { + if (*x1 != 0) + break; + if (x1 == x0) { + *x1 = 1; + break; + } + } + return STRTOG_NaNbits; + } diff --git a/gdtoa/FreeBSD/gdtoa-misc.c b/gdtoa/FreeBSD/gdtoa-misc.c new file mode 100644 index 0000000..5f5cbc2 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-misc.c @@ -0,0 +1,862 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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 & 1) + 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 +#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; + int de, i, 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; + i = 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; + i = 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/FreeBSD/gdtoa-smisc.c b/gdtoa/FreeBSD/gdtoa-smisc.c new file mode 100644 index 0000000..e20e9da --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-smisc.c @@ -0,0 +1,197 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + Bigint * +s2b +#ifdef KR_headers + (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; +#else + (CONST char *s, int nd0, int nd, ULong y9) +#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++; + } + else + s += 10; + 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/FreeBSD/gdtoa-strtoIg.c b/gdtoa/FreeBSD/gdtoa-strtoIg.c new file mode 100644 index 0000000..a766813 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-strtoIg.c @@ -0,0 +1,139 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp; +#else +strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) +#endif +{ + Bigint *b, *b1; + int i, nb, nw, nw1, rv, rv1, swap; + unsigned int nb1, nb11; + Long e1; + + b = *B; + rv = strtodg(s00, se, fpi, exp, b->x); + if (!(rv & STRTOG_Inexact)) { + B[1] = 0; + return *rvp = rv; + } + e1 = exp[0]; + rv1 = rv ^ STRTOG_Inexact; + b1 = Balloc(b->k); + Bcopy(b1, b); + nb = fpi->nbits; + nb1 = nb & 31; + nb11 = (nb1 - 1) & 31; + nw = b->wds; + nw1 = nw - 1; + if (rv & STRTOG_Inexlo) { + swap = 0; + b1 = increment(b1); + if (fpi->sudden_underflow + && (rv & STRTOG_Retmask) == STRTOG_Zero) { + b1->x[0] = 0; + b1->x[nw1] = 1L << nb11; + rv1 += STRTOG_Normal - STRTOG_Zero; + rv1 &= ~STRTOG_Underflow; + goto swapcheck; + } + if (b1->wds > nw + || nb1 && b1->x[nw1] & 1L << nb1) { + if (++e1 > fpi->emax) + rv1 = STRTOG_Infinite | STRTOG_Inexhi; + rshift(b1, 1); + } + else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + if (b1->x[nw1] & 1L << nb11) { + rv1 += STRTOG_Normal - STRTOG_Denormal; + rv1 &= ~STRTOG_Underflow; + } + } + } + else { + swap = STRTOG_Neg; + if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { + b1 = set_ones(b1, nb); + e1 = fpi->emax; + rv1 = STRTOG_Normal | STRTOG_Inexlo; + goto swapcheck; + } + decrement(b1); + if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + for(i = nw1; !b1->x[i]; --i) + if (!i) { + rv1 = STRTOG_Zero | STRTOG_Inexlo; + break; + } + goto swapcheck; + } + if (!(b1->x[nw1] & 1L << nb11)) { + if (e1 == fpi->emin) { + if (fpi->sudden_underflow) + rv1 += STRTOG_Zero - STRTOG_Normal; + else + rv1 += STRTOG_Denormal - STRTOG_Normal; + rv1 |= STRTOG_Underflow; + } + else { + b1 = lshift(b1, 1); + b1->x[0] |= 1; + --e1; + } + } + } + swapcheck: + if (swap ^ (rv & STRTOG_Neg)) { + rvp[0] = rv1; + rvp[1] = rv; + B[0] = b1; + B[1] = b; + exp[1] = exp[0]; + exp[0] = e1; + } + else { + rvp[0] = rv; + rvp[1] = rv1; + B[1] = b1; + exp[1] = e1; + } + return rv; + } diff --git a/gdtoa/FreeBSD/gdtoa-strtod.c b/gdtoa/FreeBSD/gdtoa-strtod.c new file mode 100644 index 0000000..f1a0c04 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-strtod.c @@ -0,0 +1,964 @@ +/**************************************************************** + +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@acm.org + */ + +#include "gdtoaimp.h" + +#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 +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (CONST char *s00, char **se) +#endif +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, 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; +#endif + + sign = nz0 = nz = 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': + switch(i = gethex(&s, &fpi, &exp, &bb, sign)) { + case STRTOG_NoNumber: + s = s00; + sign = 0; + case STRTOG_Zero: + break; + default: + 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; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + c = *++s; + 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 }; + 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 { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; + } +#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 = Flt_Rounds) >= 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 */ + + bd0 = s2b(s0, nd0, nd, y); + + 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 (word0(rv) == 0 && word1(rv) == 0) + 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); + } + diff --git a/gdtoa/FreeBSD/gdtoa-strtodg.c b/gdtoa/FreeBSD/gdtoa-strtodg.c new file mode 100644 index 0000000..bf30e33 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-strtodg.c @@ -0,0 +1,1001 @@ +/**************************************************************** + +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@acm.org + */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + static 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; + } + + static 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; + } + + static 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 = 32 - 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; + } + + static 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); + } + + int +strtodg +#ifdef KR_headers + (s00, se, fpi, exp, bits) + CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; +#else + (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits) +#endif +{ + int abe, abits, asub; + int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2; + int c, denorm, 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; + + 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); + 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(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; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + c = *++s; + 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 */ + 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]; + } + } + + 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) { + rvb->wds = 0; + irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + infnanexp: + *exp = fpi->emax + 1; + goto ret; + } + 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; + 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 */ + + bd0 = s2b(s0, nd0, nd, y); + + 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 >> kshift) !=0) + j = 32 - j; + if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift]) + != 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 && rvbits < nbits) { + j = nbits - rvbits; + rvb = lshift(rvb, j); + rve -= j; + } + *exp = rve; + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + 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); + } + return irv; + } diff --git a/gdtoa/FreeBSD/gdtoa-strtof.c b/gdtoa/FreeBSD/gdtoa-strtof.c new file mode 100644 index 0000000..bb283ae --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-strtof.c @@ -0,0 +1,83 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#include "gdtoaimp.h" + + float +#ifdef KR_headers +strtof(s, sp) CONST char *s; char **sp; +#else +strtof(CONST char *s, char **sp) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 1 }; +#else + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; +#endif + ULong bits[1]; + Long exp; + int k; + union { ULong L[1]; float f; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + 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] = 0x7fffffff; + } + if (k & STRTOG_Neg) + u.L[0] |= 0x80000000L; + return u.f; + } diff --git a/gdtoa/FreeBSD/gdtoa-strtord.c b/gdtoa/FreeBSD/gdtoa-strtord.c new file mode 100644 index 0000000..12213f9 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-strtord.c @@ -0,0 +1,99 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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] = 0x7fffffff; + L[_1] = (ULong)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d; +#else +strtord(CONST char *s, char **sp, int rounding, double *d) +#endif +{ + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/gdtoa/FreeBSD/gdtoa-sum.c b/gdtoa/FreeBSD/gdtoa-sum.c new file mode 100644 index 0000000..1e1a4de --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-sum.c @@ -0,0 +1,104 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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/FreeBSD/gdtoa-ulp.c b/gdtoa/FreeBSD/gdtoa-ulp.c new file mode 100644 index 0000000..536994a --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa-ulp.c @@ -0,0 +1,76 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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/FreeBSD/gdtoa.h b/gdtoa/FreeBSD/gdtoa.h new file mode 100644 index 0000000..62553f2 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa.h @@ -0,0 +1,159 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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/FreeBSD/gdtoa_strtopx.c b/gdtoa/FreeBSD/gdtoa_strtopx.c new file mode 100644 index 0000000..190b80f --- /dev/null +++ b/gdtoa/FreeBSD/gdtoa_strtopx.c @@ -0,0 +1,106 @@ +/**************************************************************** + +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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +#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) CONST char *s; char **sp; void *V; +#else +strtopx(CONST char *s, char **sp, void *V) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 1 }; +#else + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; +#endif + ULong bits[2]; + Long exp; + int k; + UShort *L = (UShort*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + L[_0] = exp + 0x3fff + 63; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = (UShort)-1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + return k; + } diff --git a/gdtoa/FreeBSD/gdtoaimp.h b/gdtoa/FreeBSD/gdtoaimp.h new file mode 100644 index 0000000..dd398e4 --- /dev/null +++ b/gdtoa/FreeBSD/gdtoaimp.h @@ -0,0 +1,688 @@ +/**************************************************************** + +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. + +****************************************************************/ + +/* $FreeBSD: src/contrib/gdtoa/gdtoaimp.h,v 1.5 2003/04/09 06:04:35 das Exp $ */ + +/* 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 + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* 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. 92-101]. + * + * 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). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * 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 "gdtoa.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" +#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 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)); + extern void hexdig_init_D2A(Void); + extern int hexnan ANSI((CONST char**, FPI*, ULong*)); + extern int hi0bits 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)); + extern Bigint *set_ones ANSI((Bigint*, int)); + extern char *strcp ANSI((char*, const char*)); + extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); + + 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 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 *)); + extern int strtopx ANSI((CONST char *, char **, Void *)); + 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 + + +#ifdef IEEE_Arith +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#else +#define _0 1 +#define _1 0 +#endif +#else +#undef INFNAN_CHECK +#endif + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif +#endif /* INFNAN_CHECK */ + +#undef SI +#ifdef Sudden_Underflow +#define SI 1 +#else +#define SI 0 +#endif + +#endif /* GDTOAIMP_H_INCLUDED */ diff --git a/gdtoa/FreeBSD/glue.c b/gdtoa/FreeBSD/glue.c new file mode 100644 index 0000000..0db1914 --- /dev/null +++ b/gdtoa/FreeBSD/glue.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/FreeBSD/machdep_ldisQ.c b/gdtoa/FreeBSD/machdep_ldisQ.c new file mode 100644 index 0000000..fca9c29 --- /dev/null +++ b/gdtoa/FreeBSD/machdep_ldisQ.c @@ -0,0 +1,45 @@ +/*- + * 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 + * uses quad precision, such as sparc64. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gdtoa/machdep_ldisQ.c,v 1.2 2003/04/09 05:58:43 das Exp $"); + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtopQ(s, sp, &result); + return result; +} diff --git a/gdtoa/FreeBSD/machdep_ldisd.c b/gdtoa/FreeBSD/machdep_ldisd.c new file mode 100644 index 0000000..2e20e17 --- /dev/null +++ b/gdtoa/FreeBSD/machdep_ldisd.c @@ -0,0 +1,43 @@ +/*- + * 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 the same as a double, such as the Alpha. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gdtoa/machdep_ldisd.c,v 1.1 2003/03/12 20:29:58 das Exp $"); + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + + return strtod(s, sp); +} diff --git a/gdtoa/FreeBSD/machdep_ldisx.c b/gdtoa/FreeBSD/machdep_ldisx.c new file mode 100644 index 0000000..0ceea1b --- /dev/null +++ b/gdtoa/FreeBSD/machdep_ldisx.c @@ -0,0 +1,45 @@ +/*- + * 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 "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtopx(s, sp, &result); + return result; +} diff --git a/gdtoa/Makefile.inc b/gdtoa/Makefile.inc new file mode 100644 index 0000000..aaf7c85 --- /dev/null +++ b/gdtoa/Makefile.inc @@ -0,0 +1,15 @@ +.PATH: ${.CURDIR}/gdtoa + +CFLAGS += -I${.CURDIR}/gdtoa + +.include "Makefile.fbsd_begin" +FBSDSRCS= _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-strtoIg.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 +FBSDORIGHDRS= gdtoa.h gdtoaimp.h +.include "Makefile.fbsd_end" diff --git a/gdtoa/arith.h b/gdtoa/arith.h new file mode 100644 index 0000000..610afab --- /dev/null +++ b/gdtoa/arith.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * These values generated by arithchk.c in the FreeBSD contrib/gdtoa package + * and spliced together for the different architectures. + */ + +#if defined(__ppc__) +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align +#elif defined(__i386__) +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#else +#error Unsupported architecture +#endif diff --git a/gen/_rand48.c b/gen/FreeBSD/_rand48.c similarity index 92% rename from gen/_rand48.c rename to gen/FreeBSD/_rand48.c index 990e2c8..4dbf0d7 100644 --- a/gen/_rand48.c +++ b/gen/FreeBSD/_rand48.c @@ -11,6 +11,9 @@ * 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" unsigned short _rand48_seed[3] = { diff --git a/gen/alarm.3 b/gen/FreeBSD/alarm.3 similarity index 97% rename from gen/alarm.3 rename to gen/FreeBSD/alarm.3 index d2725b1..e9be94f 100644 --- a/gen/alarm.3 +++ b/gen/FreeBSD/alarm.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)alarm.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/alarm.3,v 1.15 2001/10/01 16:08:50 ru Exp $ +.\" $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 @@ -69,7 +69,7 @@ alarm and the signal SIGALRM will not be delivered. Due to .Xr setitimer 2 restriction the maximum number of -.Ar seconds +.Fa seconds allowed is 100000000. .Sh RETURN VALUES The return value of diff --git a/gen/alarm.c b/gen/FreeBSD/alarm.c similarity index 67% rename from gen/alarm.c rename to gen/FreeBSD/alarm.c index 0f55380..58cce20 100644 --- a/gen/alarm.c +++ b/gen/FreeBSD/alarm.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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. @@ -67,7 +48,7 @@ alarm(secs) unsigned int secs; { struct itimerval it, oitv; - register struct itimerval *itp = ⁢ + struct itimerval *itp = ⁢ timerclear(&itp->it_interval); itp->it_value.tv_sec = secs; diff --git a/gen/basename.3 b/gen/FreeBSD/basename.3 similarity index 95% rename from gen/basename.3 rename to gen/FreeBSD/basename.3 index 3385318..374bac0 100644 --- a/gen/basename.3 +++ b/gen/FreeBSD/basename.3 @@ -25,7 +25,7 @@ .\" 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.4 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/basename.3,v 1.6 2002/12/18 13:33:02 ru Exp $ .\" .Dd August 17, 1997 .Dt BASENAME 3 @@ -42,19 +42,19 @@ The .Fn basename function returns the last component from the pathname pointed to by -.Ar path , +.Fa path , deleting any trailing .Sq \&/ characters. If -.Ar path +.Fa path consists entirely of .Sq \&/ characters, a pointer to the string .Qq \&/ is returned. If -.Ar path +.Fa path is a null pointer or the empty string, a pointer to the string .Qq \&. is returned. @@ -62,7 +62,7 @@ is returned. On successful completion, .Fn basename returns a pointer to the last component of -.Ar path . +.Fa path . .Pp If .Fn basename @@ -78,7 +78,9 @@ 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. .Sh SEE ALSO diff --git a/gen/basename.c b/gen/FreeBSD/basename.c similarity index 88% rename from gen/basename.c rename to gen/FreeBSD/basename.c index a138177..c5da463 100644 --- a/gen/basename.c +++ b/gen/FreeBSD/basename.c @@ -1,6 +1,3 @@ -/* $OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */ -/* $FreeBSD: src/lib/libc/gen/basename.c,v 1.1.2.2 2001/07/23 10:13:04 dd Exp $ */ - /* * Copyright (c) 1997 Todd C. Miller * All rights reserved. @@ -28,27 +25,31 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(LIBC_RCS) && !defined(lint) +#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 -#include char * basename(path) const char *path; { static char *bname = NULL; - register const char *endp, *startp; + const char *endp, *startp; - if( bname == NULL ) { - bname = malloc(MAXPATHLEN); - if( bname == NULL ) - return NULL; + if (bname == NULL) { + bname = (char *)malloc(MAXPATHLEN); + if (bname == NULL) + return(NULL); } /* Empty or NULL string gets treated as "." */ diff --git a/gen/clock.3 b/gen/FreeBSD/clock.3 similarity index 96% rename from gen/clock.3 rename to gen/FreeBSD/clock.3 index 2f053a6..cff60dc 100644 --- a/gen/clock.3 +++ b/gen/FreeBSD/clock.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)clock.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/clock.3,v 1.10 2001/11/05 21:30:43 dwmalone Exp $ +.\" $FreeBSD: src/lib/libc/gen/clock.3,v 1.11 2001/11/20 13:43:58 ru Exp $ .\" .Dd June 4, 1993 .Dt CLOCK 3 @@ -70,7 +70,7 @@ The function conforms to .St -isoC . However, -.St -susv2 +.St -susv2 requires .Dv CLOCKS_PER_SEC to be defined as one million. diff --git a/gen/clock.c b/gen/FreeBSD/clock.c similarity index 64% rename from gen/clock.c rename to gen/FreeBSD/clock.c index 2411a5b..ddfccbe 100644 --- a/gen/clock.c +++ b/gen/FreeBSD/clock.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,16 +31,22 @@ * 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 * CLK_TCK) / 1000000, + * 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 * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) +#define CONVTCK(r) ((r).tv_sec * CLOCKS_PER_SEC \ + + (r).tv_usec / (1000000 / CLOCKS_PER_SEC)) clock_t clock() diff --git a/gen/closedir.c b/gen/FreeBSD/closedir.c similarity index 60% rename from gen/closedir.c rename to gen/FreeBSD/closedir.c index fdf103c..31dedc0 100644 --- a/gen/closedir.c +++ b/gen/FreeBSD/closedir.c @@ -1,30 +1,6 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. + * 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 @@ -55,25 +31,44 @@ * 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) - register DIR *dirp; + DIR *dirp; { int fd; - seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + _seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */ fd = dirp->dd_fd; dirp->dd_fd = -1; dirp->dd_loc = 0; - (void)free((void *)dirp->dd_buf); - (void)free((void *)dirp); - return(close(fd)); + 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/ctermid.3 b/gen/FreeBSD/ctermid.3 similarity index 96% rename from gen/ctermid.3 rename to gen/FreeBSD/ctermid.3 index 8206dcd..a15fbd7 100644 --- a/gen/ctermid.3 +++ b/gen/FreeBSD/ctermid.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctermid.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.8 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.10 2002/12/18 13:33:02 ru Exp $ .\" .Dd June 4, 1993 .Dt CTERMID 3 @@ -53,14 +53,14 @@ function generates a string, that, when used as a pathname, refers to the current controlling terminal of the calling process. .Pp If -.Ar buf +.Fa buf is the .Dv NULL pointer, a pointer to a static area is returned. Otherwise, the pathname is copied into the memory referenced by -.Ar buf . +.Fa buf . The argument -.Ar buf +.Fa buf is assumed to be at least .Dv L_ctermid (as defined in the include @@ -68,11 +68,13 @@ file .Aq Pa stdio.h ) bytes long. .Pp +The .Fn ctermid_r +function provides the same functionality as .Fn ctermid except that if -.Ar buf +.Fa buf is a .Dv NULL pointer, diff --git a/gen/ctermid.c b/gen/FreeBSD/ctermid.c similarity index 65% rename from gen/ctermid.c rename to gen/FreeBSD/ctermid.c index 1aa6b1b..6b2c682 100644 --- a/gen/ctermid.c +++ b/gen/FreeBSD/ctermid.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,14 +31,18 @@ * 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(s) - char *s; +ctermid(char *s) { static char def[] = _PATH_TTY; @@ -72,3 +52,10 @@ ctermid(s) } return(def); } + + +char * +ctermid_r(char *s) +{ + return (s) ? ctermid(s) : NULL; +} diff --git a/gen/daemon.3 b/gen/FreeBSD/daemon.3 similarity index 71% rename from gen/daemon.3 rename to gen/FreeBSD/daemon.3 index 0a95ff8..5efef13 100644 --- a/gen/daemon.3 +++ b/gen/FreeBSD/daemon.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)daemon.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/daemon.3,v 1.10 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/daemon.3,v 1.12 2002/01/16 15:21:39 ru Exp $ .\" .Dd June 9, 1993 .Dt DAEMON 3 @@ -54,20 +54,23 @@ Unless the argument .Fa nochdir is non-zero, .Fn daemon -changes the current working directory to the root (``/''). +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 ``/dev/null''. +will redirect standard input, standard output, and standard error to +.Pa /dev/null . +.Sh RETURN VALUES +.Rv -std daemon .Sh ERRORS -If an error occurs, +The .Fn daemon -returns -1 and sets the global variable +function may fail and set .Va errno -to any of the errors specified for the library functions +for any of the errors specified for the library functions .Xr fork 2 and .Xr setsid 2 . @@ -79,3 +82,22 @@ 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. diff --git a/gen/daemon.c b/gen/FreeBSD/daemon.c similarity index 63% rename from gen/daemon.c rename to gen/FreeBSD/daemon.c index d3fe04b..63185d6 100644 --- a/gen/daemon.c +++ b/gen/FreeBSD/daemon.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,10 +31,17 @@ * 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.5 2002/02/01 00:57:29 obrien Exp $"); +#include "namespace.h" #include #include #include +#include "un-namespace.h" int daemon(nochdir, noclose) @@ -81,12 +64,12 @@ daemon(nochdir, noclose) 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 (!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); + (void)_close(fd); } return (0); } diff --git a/gen/dirname.3 b/gen/FreeBSD/dirname.3 similarity index 94% rename from gen/dirname.3 rename to gen/FreeBSD/dirname.3 index 2b160a9..5947140 100644 --- a/gen/dirname.3 +++ b/gen/FreeBSD/dirname.3 @@ -25,14 +25,14 @@ .\" 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.4 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/dirname.3,v 1.7 2002/12/27 12:15:28 schweikh Exp $ .\" .Dd August 17, 1997 .Dt DIRNAME 3 .Os .Sh NAME .Nm dirname -.Nd extract the directory portition of a pathname +.Nd extract the directory part of a pathname .Sh SYNOPSIS .In libgen.h .Ft char * @@ -44,13 +44,13 @@ function is the converse of .Xr basename 3 ; it returns a pointer to the parent directory of the pathname pointed to by -.Ar path . +.Fa path . Any trailing .Sq \&/ characters are not counted as part of the directory name. If -.Ar path +.Fa path is a null pointer, the empty string, or contains no .Sq \&/ characters, @@ -62,7 +62,7 @@ signifying the current directory. On successful completion, .Fn dirname returns a pointer to the parent directory of -.Ar path . +.Fa path . .Pp If .Fn dirname @@ -78,7 +78,9 @@ 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 diff --git a/gen/dirname.c b/gen/FreeBSD/dirname.c similarity index 89% rename from gen/dirname.c rename to gen/FreeBSD/dirname.c index 709c157..8a4e1c9 100644 --- a/gen/dirname.c +++ b/gen/FreeBSD/dirname.c @@ -1,6 +1,3 @@ -/* $OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */ -/* $FreeBSD: src/lib/libc/gen/dirname.c,v 1.1.2.2 2001/07/23 10:13:04 dd Exp $ */ - /* * Copyright (c) 1997 Todd C. Miller * All rights reserved. @@ -28,27 +25,31 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(LIBC_RCS) && !defined(lint) +#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 -#include char * dirname(path) const char *path; { static char *bname = NULL; - register const char *endp; + const char *endp; - if ( bname == NULL ) { - bname = malloc(MAXPATHLEN); - if( bname == NULL ) - return NULL; + if (bname == NULL) { + bname = (char *)malloc(MAXPATHLEN); + if (bname == NULL) + return(NULL); } /* Empty or NULL string gets treated as "." */ diff --git a/gen/drand48.c b/gen/FreeBSD/drand48.c similarity index 83% rename from gen/drand48.c rename to gen/FreeBSD/drand48.c index cec04a6..92aeb80 100644 --- a/gen/drand48.c +++ b/gen/FreeBSD/drand48.c @@ -11,6 +11,9 @@ * 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" extern unsigned short _rand48_seed[3]; diff --git a/gen/erand48.c b/gen/FreeBSD/erand48.c similarity index 85% rename from gen/erand48.c rename to gen/FreeBSD/erand48.c index 286904c..4b0c1df 100644 --- a/gen/erand48.c +++ b/gen/FreeBSD/erand48.c @@ -11,6 +11,9 @@ * 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 diff --git a/gen/err.3 b/gen/FreeBSD/err.3 similarity index 98% rename from gen/err.3 rename to gen/FreeBSD/err.3 index 08e6316..75e5f2b 100644 --- a/gen/err.3 +++ b/gen/FreeBSD/err.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)err.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/err.3,v 1.18 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/err.3,v 1.19 2002/08/05 06:49:58 mike Exp $ .\" .Dd March 6, 1999 .Dt ERR 3 @@ -207,6 +207,7 @@ if (error != 0) .Ed .Sh SEE ALSO .Xr exit 3 , +.Xr fmtmsg 3 , .Xr printf 3 , .Xr strerror 3 .Sh HISTORY diff --git a/gen/err.c b/gen/FreeBSD/err.c similarity index 51% rename from gen/err.c rename to gen/FreeBSD/err.c index 21a908a..aa0d306 100644 --- a/gen/err.c +++ b/gen/FreeBSD/err.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* +/*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -55,110 +31,129 @@ * 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 "un-namespace.h" -#include +#include "libc_private.h" -#ifdef __STDC__ -#include -#else -#include -#endif - -__dead void -#ifdef __STDC__ -err(int eval, const char *fmt, ...) -#else -err(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif +static FILE *err_file; /* file to use for error output */ +static void (*err_exit)(int); + +/* + * 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) + err_file = fp; + else + err_file = stderr; +} + +void +err_set_exit(void (*ef)(int)) +{ + err_exit = ef; +} + +__weak_reference(_err, err); + +void +_err(int eval, const char *fmt, ...) { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif - verr(eval, fmt, ap); + verrc(eval, errno, fmt, ap); va_end(ap); } -__dead void +void verr(eval, fmt, ap) int eval; const char *fmt; va_list ap; { - char* __progname = *(*_NSGetArgv()); - int sverrno; + verrc(eval, errno, fmt, ap); +} - sverrno = errno; - (void)fprintf(stderr, "%s: ", __progname); +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 (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) { - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, ": "); + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); } - (void)fprintf(stderr, "%s\n", strerror(sverrno)); + fprintf(err_file, "%s\n", strerror(code)); + if (err_exit) + err_exit(eval); exit(eval); } -__dead void -#if __STDC__ +void errx(int eval, const char *fmt, ...) -#else -errx(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif verrx(eval, fmt, ap); va_end(ap); } -__dead void +void verrx(eval, fmt, ap) int eval; const char *fmt; va_list ap; { - char* __progname = *(*_NSGetArgv()); - (void)fprintf(stderr, "%s: ", __progname); + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); + if (err_exit) + err_exit(eval); exit(eval); } +__weak_reference(_warn, warn); + void -#if __STDC__ -warn(const char *fmt, ...) -#else -warn(fmt, va_alist) - const char *fmt; - va_dcl -#endif +_warn(const char *fmt, ...) { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif - vwarn(fmt, ap); + vwarnc(errno, fmt, ap); va_end(ap); } @@ -167,31 +162,39 @@ vwarn(fmt, ap) const char *fmt; va_list ap; { - int sverrno = errno; - char* __progname = *(*_NSGetArgv()); - (void)fprintf(stderr, "%s: ", __progname); + 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 (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) { - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, ": "); + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); } - (void)fprintf(stderr, "%s\n", strerror(sverrno)); + fprintf(err_file, "%s\n", strerror(code)); } void -#ifdef __STDC__ warnx(const char *fmt, ...) -#else -warnx(fmt, va_alist) - const char *fmt; - va_dcl -#endif { va_list ap; -#ifdef __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif vwarnx(fmt, ap); va_end(ap); } @@ -201,9 +204,10 @@ vwarnx(fmt, ap) const char *fmt; va_list ap; { - char* __progname = *(*_NSGetArgv()); - (void)fprintf(stderr, "%s: ", __progname); + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); } diff --git a/gen/FreeBSD/errno_.c b/gen/FreeBSD/errno_.c new file mode 100644 index 0000000..7d98857 --- /dev/null +++ b/gen/FreeBSD/errno_.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.3 b/gen/FreeBSD/exec.3 similarity index 95% rename from gen/exec.3 rename to gen/FreeBSD/exec.3 index 69d4dfa..82f3c15 100644 --- a/gen/exec.3 +++ b/gen/FreeBSD/exec.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)exec.3 8.3 (Berkeley) 1/24/94 -.\" $FreeBSD: src/lib/libc/gen/exec.3,v 1.16 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/exec.3,v 1.18 2002/12/19 09:40:21 ru Exp $ .\" .Dd January 24, 1994 .Dt EXEC 3 @@ -118,9 +118,9 @@ and functions also specify the environment of the executed process by following the .Dv NULL -pointer that terminates the list of arguments in the parameter list -or the pointer to the argv array with an additional parameter. -This additional parameter is an array of pointers to null-terminated strings +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 @@ -203,11 +203,13 @@ will be set to indicate the error. The shell. .El .Sh ERRORS -.Fn Execl , +The +.Fn execl , .Fn execle , .Fn execlp and .Fn execvp +functions may fail and set .Va errno for any of the errors specified for the library functions @@ -215,9 +217,11 @@ for any of the errors specified for the library functions and .Xr malloc 3 . .Pp -.Fn Exect +The +.Fn exect and .Fn execv +functions may fail and set .Va errno for any of the errors specified for the library function @@ -286,11 +290,13 @@ and the unusual error The behaviour was changed to match the behaviour of .Xr sh 1 . .Sh STANDARDS -.Fn Execl , +The +.Fn execl , .Fn execv , .Fn execle , .Fn execlp and .Fn execvp +functions conform to .St -p1003.1-88 . diff --git a/gen/FreeBSD/exec.c b/gen/FreeBSD/exec.c new file mode 100644 index 0000000..a22d31b --- /dev/null +++ b/gen/FreeBSD/exec.c @@ -0,0 +1,266 @@ +/*- + * 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.20 2003/01/03 23:16:55 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "un-namespace.h" + +extern char **environ; + +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(name, argv) + const char *name; + char * const *argv; +{ + char **memp; + int cnt, lp, ln; + char *p; + int eacces, save_errno; + char *bp, *cur, *path, 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 = path = 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); + } + + /* Get the path we're searching. */ + if (!(path = getenv("PATH"))) + path = _PATH_DEFPATH; + cur = alloca(strlen(path) + 1); + if (cur == NULL) { + errno = ENOMEM; + return (-1); + } + strcpy(cur, path); + path = cur; + while ( (p = strsep(&cur, ":")) ) { + /* + * It's a SHELL path -- double, leading and trailing colons + * mean the current directory. + */ + if (!*p) { + 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 + errno = ENOENT; +done: + return (-1); +} diff --git a/gen/FreeBSD/exec.c.patch b/gen/FreeBSD/exec.c.patch new file mode 100644 index 0000000..60d70c1 --- /dev/null +++ b/gen/FreeBSD/exec.c.patch @@ -0,0 +1,12 @@ +--- exec.c.orig Fri Jan 3 15:16:55 2003 ++++ exec.c Sat May 3 14:03:35 2003 +@@ -51,7 +51,8 @@ + #include + #include "un-namespace.h" + +-extern char **environ; ++#include ++#define environ (*_NSGetEnviron()) + + int + execl(const char *name, const char *arg, ...) diff --git a/gen/fmtcheck.3 b/gen/FreeBSD/fmtcheck.3 similarity index 89% rename from gen/fmtcheck.3 rename to gen/FreeBSD/fmtcheck.3 index ec67305..a2068e1 100644 --- a/gen/fmtcheck.3 +++ b/gen/FreeBSD/fmtcheck.3 @@ -31,8 +31,8 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/fmtcheck.3,v 1.4 2001/10/01 16:08:50 ru Exp $ -.Dd October 17, 2000 +.\" $FreeBSD: src/lib/libc/gen/fmtcheck.3,v 1.8 2002/12/19 09:40:21 ru Exp $ +.Dd October 16, 2002 .Os .Dt FMTCHECK 3 .Sh NAME @@ -63,11 +63,11 @@ is a valid format string. .Pp The .Xr printf 3 -family of functions can not verify the types of arguments that they are +family of functions cannot verify the types of arguments that they are passed at run-time. In some cases, like .Xr catgets 3 , it is useful or necessary to use a user-supplied format string with no -guarantee that the format string matches the specified parameters. +guarantee that the format string matches the specified arguments. .Pp The .Fn fmtcheck @@ -81,18 +81,6 @@ the field width or precision is an asterisk .Ql * instead of a digit string). Also, any text other than the format specifiers is completely ignored. -.Pp -Note that the formats may be quite different as long as they accept the -same parameters. For example, -.Qq Li "%p %o %30s %#llx %-10.*e %n" -is compatible with -.Qq Li "This number %lu %d%% and string %s has %qd numbers and %.*g floats (%n)" . -However, -.Qq Li %o -is not equivalent to -.Qq Li %lx -because -the first requires an integer and the second requires a long. .Sh RETURN VALUES If .Fa fmt_suspect @@ -104,5 +92,23 @@ will return .Fa fmt_suspect . Otherwise, it will return .Fa fmt_default . +.Sh SECURITY CONSIDERATIONS +Note that the formats may be quite different as long as they accept the +same arguments. For example, +.Qq Li "%p %o %30s %#llx %-10.*e %n" +is compatible with +.Qq Li "This number %lu %d%% and string %s has %qd numbers and %.*g floats (%n)" . +However, +.Qq Li %o +is not equivalent to +.Qq Li %lx +because +the first requires an integer and the second requires a long. .Sh SEE ALSO .Xr printf 3 +.Sh BUGS +The +.Fn fmtcheck +function does not understand all of the conversions that +.Xr printf 3 +does. diff --git a/gen/FreeBSD/fmtcheck.c b/gen/FreeBSD/fmtcheck.c new file mode 100644 index 0000000..92593a6 --- /dev/null +++ b/gen/FreeBSD/fmtcheck.c @@ -0,0 +1,243 @@ +/*- + * 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.5 2002/06/27 13:20:54 deischen Exp $"); + +#include +#include +#include + +__weak_reference(__fmtcheck, fmtcheck); + +enum __e_fmtcheck_types { + FMTCHECK_START, + FMTCHECK_SHORT, + FMTCHECK_INT, + FMTCHECK_LONG, + FMTCHECK_QUAD, + FMTCHECK_SHORTPOINTER, + FMTCHECK_INTPOINTER, + FMTCHECK_LONGPOINTER, + FMTCHECK_QUADPOINTER, + FMTCHECK_DOUBLE, + FMTCHECK_LONGDOUBLE, + 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; + const char *f; + + sh = lg = quad = longdouble = 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 '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); + 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); + RETURN(pf,f,FMTCHECK_INTPOINTER); + } + if (strchr("DOU", *f)) { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_LONG); + } + if (strchr("eEfg", *f)) { + if (longdouble) + RETURN(pf,f,FMTCHECK_LONGDOUBLE); + if (sh + lg + quad) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_DOUBLE); + } + if (*f == 'c') { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_INT); + } + if (*f == 's') { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_STRING); + } + if (*f == 'p') { + if (sh + lg + quad + longdouble) + 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/fnmatch.3 b/gen/FreeBSD/fnmatch.3 similarity index 97% rename from gen/fnmatch.3 rename to gen/FreeBSD/fnmatch.3 index 7442408..6b98af2 100644 --- a/gen/fnmatch.3 +++ b/gen/FreeBSD/fnmatch.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fnmatch.3 8.3 (Berkeley) 4/28/95 -.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.9.2.3 2001/12/14 18:33:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/fnmatch.3,v 1.14 2002/12/18 13:33:02 ru Exp $ .\" .Dd April 28, 1995 .Dt FNMATCH 3 @@ -101,7 +101,7 @@ is related to the specification of A period is always .Dq leading if it is the first character in -.Ar string . +.Fa string . Additionally, if .Dv FNM_PATHNAME is set, @@ -110,7 +110,7 @@ leading if it immediately follows a slash. .It Dv FNM_LEADING_DIR Ignore -.Nm /* +.Dq Li /* rest after successful .Fa pattern matching. diff --git a/gen/fnmatch.c b/gen/FreeBSD/fnmatch.c similarity index 97% rename from gen/fnmatch.c rename to gen/FreeBSD/fnmatch.c index c3312b4..7b6f10d 100644 --- a/gen/fnmatch.c +++ b/gen/FreeBSD/fnmatch.c @@ -37,6 +37,8 @@ #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.15 2002/02/01 01:32:19 obrien Exp $"); /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. @@ -56,7 +58,7 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) -static int rangematch __P((const char *, char, int, char **)); +static int rangematch(const char *, char, int, char **); int fnmatch(pattern, string, flags) diff --git a/gen/ftok.3 b/gen/FreeBSD/ftok.3 similarity index 94% rename from gen/ftok.3 rename to gen/FreeBSD/ftok.3 index b706e88..2359013 100644 --- a/gen/ftok.3 +++ b/gen/FreeBSD/ftok.3 @@ -23,7 +23,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.14 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/ftok.3,v 1.15 2002/10/19 13:33:12 tjr Exp $ .Dd June 24, 1994 .Os .Dt FTOK 3 @@ -38,9 +38,6 @@ .Ft key_t .Fn ftok "const char *path" "int id" .Sh DESCRIPTION -.Bf -symbolic -This function is available from the compatibility library, libcompat. -.Ef The .Fn ftok function attempts to create a unique key suitable for use with the diff --git a/gen/ftok.c b/gen/FreeBSD/ftok.c similarity index 86% rename from gen/ftok.c rename to gen/FreeBSD/ftok.c index fc70f62..9a5c72d 100644 --- a/gen/ftok.c +++ b/gen/FreeBSD/ftok.c @@ -25,9 +25,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$Id: ftok.c,v 1.1.1.1 1999/10/14 21:08:51 wsanchez Exp $"; -#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/ftok.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); #include #include @@ -36,12 +35,12 @@ static char *rcsid = "$Id: ftok.c,v 1.1.1.1 1999/10/14 21:08:51 wsanchez Exp $"; key_t ftok(path, id) const char *path; - int id; + char id; { struct stat st; if (stat(path, &st) < 0) return (key_t)-1; - return (key_t) ((id & 0xff) << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff)); + return (key_t) (id << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff)); } diff --git a/gen/getbsize.3 b/gen/FreeBSD/getbsize.3 similarity index 97% rename from gen/getbsize.3 rename to gen/FreeBSD/getbsize.3 index 8653389..cf3bc8a 100644 --- a/gen/getbsize.3 +++ b/gen/FreeBSD/getbsize.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getbsize.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getbsize.3,v 1.8 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getbsize.3,v 1.10 2002/12/30 11:12:16 obrien Exp $ .\" .Dd June 4, 1993 .Dt GETBSIZE 3 diff --git a/gen/getbsize.c b/gen/FreeBSD/getbsize.c similarity index 71% rename from gen/getbsize.c rename to gen/FreeBSD/getbsize.c index 6ab1fec..b922f1c 100644 --- a/gen/getbsize.c +++ b/gen/FreeBSD/getbsize.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 @@ -68,7 +49,8 @@ getbsize(headerlenp, blocksizep) { static char header[20]; long n, max, mul, blocksize; - char *ep, *p, *form; + char *ep, *p; + const char *form; #define KB (1024L) #define MB (1024L * 1024L) @@ -109,7 +91,7 @@ fmterr: warnx("%s: unknown blocksize", p); break; } if (n > max) { - warnx("maximum blocksize is %dG", MAXB / GB); + warnx("maximum blocksize is %ldG", MAXB / GB); n = max; } if ((blocksize = n * mul) < 512) { @@ -120,7 +102,7 @@ underflow: warnx("minimum blocksize is 512"); } else blocksize = n = 512; - (void)snprintf(header, sizeof(header), "%d%s-blocks", n, form); + (void)snprintf(header, sizeof(header), "%ld%s-blocks", n, form); *headerlenp = strlen(header); *blocksizep = blocksize; return (header); diff --git a/gen/getcap.3 b/gen/FreeBSD/getcap.3 similarity index 98% rename from gen/getcap.3 rename to gen/FreeBSD/getcap.3 index 0af2a4f..1980a09 100644 --- a/gen/getcap.3 +++ b/gen/FreeBSD/getcap.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getcap.3 8.4 (Berkeley) 5/13/94 -.\" $FreeBSD: src/lib/libc/gen/getcap.3,v 1.20 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getcap.3,v 1.23 2002/12/30 21:18:02 schweikh Exp $ .\" .Dd May 13, 1994 .Dt GETCAP 3 @@ -94,7 +94,9 @@ function will first look for files ending in (see .Xr cap_mkdb 1 ) before accessing the ASCII file. -.Fa Buf +The +.Fa buf +argument must be retained through all subsequent calls to .Fn cgetmatch , .Fn cgetcap , @@ -106,7 +108,7 @@ but may then be .Xr free 3 Ns \&'d . On success 0 is returned, 1 if the returned record contains an unresolved -.Nm tc +.Ic tc expansion, \-1 if the requested record couldn't be found, \-2 if a system error was encountered (couldn't open/read a file, etc.) also @@ -251,8 +253,8 @@ comments below). Upon completion of the database 0 is returned, 1 is returned upon successful return of record with possibly more remaining (we haven't reached the end of the database yet), 2 is returned if the record contains an unresolved -.Nm tc -expansion, \-1 is returned if an system error occurred, and \-2 +.Ic tc +expansion, \-1 is returned if a system error occurred, and \-2 is returned if a potential reference loop is detected (see .Ic tc= comments below). @@ -284,7 +286,7 @@ By convention, the last name is usually a comment and is not intended as a lookup tag. For example, the .Em vt100 record from the -.Nm termcap +.Xr termcap 5 database begins: .Pp .Dl "d0\||\|vt100\||\|vt100-am\||\|vt100am\||\|dec vt100:" diff --git a/gen/getcap.c b/gen/FreeBSD/getcap.c similarity index 85% rename from gen/getcap.c rename to gen/FreeBSD/getcap.c index cd97da7..3cf07fa 100644 --- a/gen/getcap.c +++ b/gen/FreeBSD/getcap.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -59,20 +35,25 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getcap.c,v 1.4 1997/02/01 04:35:33 deraadt Exp $"; +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 "namespace.h" #include #include -#include -#include +#include #include #include #include #include #include #include +#include "un-namespace.h" + +#include #define BFRAG 1024 #define BSIZE 1024 @@ -88,9 +69,9 @@ 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 __P((DB *, char **, char *)); -static int getent __P((char **, u_int *, char **, int, char *, int, char *)); -static int nfcmp __P((char *, char *)); +static int cdbget(DB *, char **, const char *); +static int getent(char **, u_int *, char **, int, const char *, int, char *); +static int nfcmp(char *, char *); /* * Cgetset() allows the addition of a user specified buffer to be added @@ -98,8 +79,7 @@ static int nfcmp __P((char *, char *)); * virtual database. 0 is returned on success, -1 on failure. */ int -cgetset(ent) - char *ent; +cgetset(const char *ent) { if (ent == NULL) { if (toprec) @@ -131,11 +111,10 @@ cgetset(ent) * return NULL. */ char * -cgetcap(buf, cap, type) - char *buf, *cap; - int type; +cgetcap(char *buf, const char *cap, int type) { - register char *bp, *cp; + char *bp; + const char *cp; bp = buf; for (;;) { @@ -183,8 +162,7 @@ cgetcap(buf, cap, type) * reference loop is detected. */ int -cgetent(buf, db_array, name) - char **buf, **db_array, *name; +cgetent(char **buf, char **db_array, const char *name) { u_int dummy; @@ -210,18 +188,16 @@ cgetent(buf, db_array, name) * MAX_RECURSION. */ static int -getent(cap, len, db_array, fd, name, depth, nfield) - char **cap, **db_array, *name, *nfield; - u_int *len; - int fd, depth; +getent(char **cap, u_int *len, char **db_array, int fd, const char *name, + int depth, char *nfield) { DB *capdbp; - register char *r_end, *rp, **db_p; + 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. @@ -290,11 +266,9 @@ getent(cap, len, db_array, fd, name, depth, nfield) *cap = cbuf; return (retval); } else { - fd = open(*db_p, O_RDONLY, 0); - if (fd < 0) { - /* No error on unfound file. */ + fd = _open(*db_p, O_RDONLY, 0); + if (fd < 0) continue; - } myfd = 1; } } @@ -303,8 +277,8 @@ getent(cap, len, db_array, fd, name, depth, nfield) */ { char buf[BUFSIZ]; - register char *b_end, *bp; - register int c; + char *b_end, *bp; + int c; /* * Loop invariants: @@ -326,11 +300,11 @@ getent(cap, len, db_array, fd, name, depth, nfield) for (;;) { if (bp >= b_end) { int n; - - n = read(fd, buf, sizeof(buf)); + + n = _read(fd, buf, sizeof(buf)); if (n <= 0) { if (myfd) - (void)close(fd); + (void)_close(fd); if (n < 0) { free(record); return (-2); @@ -343,7 +317,7 @@ getent(cap, len, db_array, fd, name, depth, nfield) b_end = buf+n; bp = buf; } - + c = *bp++; if (c == '\n') { if (rp > record && *(rp-1) == '\\') { @@ -355,7 +329,7 @@ getent(cap, len, db_array, fd, name, depth, nfield) *rp++ = c; /* - * Enforce loop invariant: if no room + * Enforce loop invariant: if no room * left in record buffer, try to get * some more. */ @@ -365,11 +339,11 @@ getent(cap, len, db_array, fd, name, depth, nfield) pos = rp - record; newsize = r_end - record + BFRAG; - record = realloc(record, newsize); + record = reallocf(record, newsize); if (record == NULL) { errno = ENOMEM; if (myfd) - (void)close(fd); + (void)_close(fd); return (-2); } r_end = record + newsize; @@ -384,13 +358,13 @@ getent(cap, len, db_array, fd, name, depth, nfield) */ if (eof) break; - + /* * Toss blank lines and comments. */ if (*record == '\0' || *record == '#') continue; - + /* * See if this is the record we want ... */ @@ -416,8 +390,8 @@ getent(cap, len, db_array, fd, name, depth, nfield) * references in it ... */ tc_exp: { - register char *newicap, *s; - register int newilen; + char *newicap, *s; + int newilen; u_int ilen; int diff, iret, tclen; char *icap, *scan, *tc, *tcstart, *tcend; @@ -453,7 +427,7 @@ tc_exp: { tclen = s - tcstart; tcend = s; - iret = getent(&icap, &ilen, db_p, fd, tc, depth+1, + iret = getent(&icap, &ilen, db_p, fd, tc, depth+1, NULL); newicap = icap; /* Put into a register. */ newilen = ilen; @@ -461,7 +435,7 @@ tc_exp: { /* an error */ if (iret < -1) { if (myfd) - (void)close(fd); + (void)_close(fd); free(record); return (iret); } @@ -469,11 +443,11 @@ tc_exp: { tc_not_resolved = 1; /* couldn't resolve tc */ if (iret == -1) { - *(s - 1) = ':'; + *(s - 1) = ':'; scan = s - 1; tc_not_resolved = 1; continue; - + } } /* not interested in name field of tc'ed record */ @@ -507,11 +481,11 @@ tc_exp: { newsize = r_end - record + diff + BFRAG; tcpos = tcstart - record; tcposend = tcend - record; - record = realloc(record, newsize); + record = reallocf(record, newsize); if (record == NULL) { errno = ENOMEM; if (myfd) - (void)close(fd); + (void)_close(fd); free(icap); return (-2); } @@ -536,44 +510,48 @@ tc_exp: { */ 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); + (void)_close(fd); *len = rp - record - 1; /* don't count NUL */ if (r_end > rp) - if ((record = - realloc(record, (size_t)(rp - record))) == NULL) { + 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(capdbp, bp, name) - DB *capdbp; - char **bp, *name; +cdbget(DB *capdbp, char **bp, const char *name) { DBT key, data; + char *namebuf; - key.data = name; - key.size = strlen(name); + 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); } @@ -584,8 +562,9 @@ cdbget(capdbp, bp, name) 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); } @@ -594,10 +573,12 @@ cdbget(capdbp, bp, name) * record buf, -1 if not. */ int -cgetmatch(buf, name) - char *buf, *name; +cgetmatch(const char *buf, const char *name) { - register char *np, *bp; + const char *np, *bp; + + if (name == NULL || *name == '\0') + return -1; /* * Start search at beginning of record. @@ -636,8 +617,7 @@ cgetmatch(buf, name) int -cgetfirst(buf, db_array) - char **buf, **db_array; +cgetfirst(char **buf, char **db_array) { (void)cgetclose(); return (cgetnext(buf, db_array)); @@ -648,7 +628,7 @@ static int slash; static char **dbp; int -cgetclose() +cgetclose(void) { if (pfp != NULL) { (void)fclose(pfp); @@ -661,17 +641,15 @@ cgetclose() } /* - * Cgetnext() gets either the first or next entry in the logical database + * 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(bp, db_array) - register char **bp; - char **db_array; +cgetnext(char **bp, char **db_array) { size_t len; - int status, done; + int done, hadreaderr, i, savederrno, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; @@ -689,9 +667,14 @@ cgetnext(bp, db_array) } else { line = fgetln(pfp, &len); if (line == NULL && pfp) { - (void)fclose(pfp); - if (ferror(pfp)) { - (void)cgetclose(); + hadreaderr = ferror(pfp); + if (hadreaderr) + savederrno = errno; + fclose(pfp); + pfp = NULL; + if (hadreaderr) { + cgetclose(); + errno = savederrno; return (-1); } else { if (*++dbp == NULL) { @@ -710,7 +693,7 @@ cgetnext(bp, db_array) slash = 0; continue; } - if (isspace(*line) || + if (isspace((unsigned char)*line) || *line == ':' || *line == '#' || slash) { if (line[len - 2] == '\\') slash = 1; @@ -722,12 +705,13 @@ cgetnext(bp, db_array) slash = 1; else slash = 0; - } + } - /* + /* * Line points to a name line. */ + i = 0; done = 0; np = nbuf; for (;;) { @@ -747,9 +731,18 @@ cgetnext(bp, db_array) } else { /* name field extends beyond the line */ line = fgetln(pfp, &len); if (line == NULL && pfp) { - (void)fclose(pfp); - if (ferror(pfp)) { - (void)cgetclose(); + /* 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 @@ -757,19 +750,19 @@ cgetnext(bp, db_array) } } rp = buf; - for(cp = nbuf; *cp != NULL; cp++) + for(cp = nbuf; *cp != '\0'; cp++) if (*cp == '|' || *cp == ':') break; else *rp++ = *cp; *rp = '\0'; - /* - * XXX + /* + * XXX * Last argument of getent here should be nbuf if we want true - * sequential access in the case of duplicates. + * 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 + * 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); @@ -791,12 +784,10 @@ cgetnext(bp, db_array) * allocation failure). */ int -cgetstr(buf, cap, str) - char *buf, *cap; - char **str; +cgetstr(char *buf, const char *cap, char **str) { - register u_int m_room; - register char *bp, *mp; + u_int m_room; + char *bp, *mp; int len; char *mem; @@ -829,13 +820,17 @@ cgetstr(buf, cap, str) bp++; if (*bp == ':' || *bp == '\0') break; /* drop unfinished escape */ - *mp++ = *bp++ & 037; + 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') { - register int n, i; + int n, i; n = 0; i = 3; /* maximum of three octal digits */ @@ -885,7 +880,7 @@ cgetstr(buf, cap, str) if (m_room == 0) { size_t size = mp - mem; - if ((mem = realloc(mem, size + SFRAG)) == NULL) + if ((mem = reallocf(mem, size + SFRAG)) == NULL) return (-2); m_room = SFRAG; mp = mem + size; @@ -899,7 +894,7 @@ cgetstr(buf, cap, str) * Give back any extra memory and return value and success. */ if (m_room != 0) - if ((mem = realloc(mem, (size_t)(mp - mem))) == NULL) + if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL) return (-2); *str = mem; return (len); @@ -909,18 +904,17 @@ cgetstr(buf, cap, str) * 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 + * 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 + * -1 if the requested string capability couldn't be found, -2 if a system * error was encountered (storage allocation failure). */ int -cgetustr(buf, cap, str) - char *buf, *cap, **str; +cgetustr(char *buf, const char *cap, char **str) { - register u_int m_room; - register char *bp, *mp; + u_int m_room; + char *bp, *mp; int len; char *mem; @@ -958,7 +952,7 @@ cgetustr(buf, cap, str) if (m_room == 0) { size_t size = mp - mem; - if ((mem = realloc(mem, size + SFRAG)) == NULL) + if ((mem = reallocf(mem, size + SFRAG)) == NULL) return (-2); m_room = SFRAG; mp = mem + size; @@ -972,7 +966,7 @@ cgetustr(buf, cap, str) * Give back any extra memory and return value and success. */ if (m_room != 0) - if ((mem = realloc(mem, (size_t)(mp - mem))) == NULL) + if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL) return (-2); *str = mem; return (len); @@ -985,13 +979,11 @@ cgetustr(buf, cap, str) * numeric capability couldn't be found. */ int -cgetnum(buf, cap, num) - char *buf, *cap; - long *num; +cgetnum(char *buf, const char *cap, long *num) { - register long n; - register int base, digit; - register char *bp; + long n; + int base, digit; + char *bp; /* * Find numeric capability cap @@ -1049,15 +1041,14 @@ cgetnum(buf, cap, num) * Compare name field of record. */ static int -nfcmp(nf, rec) - char *nf, *rec; +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); diff --git a/gen/getcwd.3 b/gen/FreeBSD/getcwd.3 similarity index 100% rename from gen/getcwd.3 rename to gen/FreeBSD/getcwd.3 diff --git a/gen/getcwd.c b/gen/FreeBSD/getcwd.c similarity index 51% rename from gen/getcwd.c rename to gen/FreeBSD/getcwd.c index 1a4f0ea..e28044e 100644 --- a/gen/getcwd.c +++ b/gen/FreeBSD/getcwd.c @@ -1,29 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1991, 1993 + * 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 @@ -55,7 +31,13 @@ * 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.24 2003/01/10 02:58:25 tjr Exp $"); +#include "namespace.h" #include #include @@ -66,190 +48,31 @@ #include #include #include - -static char *getcwd_physical __P((char *, size_t)); +#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')) + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +extern int __getcwd(char *, size_t); char * getcwd(pt, size) char *pt; size_t size; { - char *pwd; - size_t pwdlen; + struct dirent *dp; + DIR *dir = NULL; dev_t dev; ino_t ino; - struct stat s; - - /* Check $PWD -- if it's right, it's fast. */ - if ((pwd = getenv("PWD")) != NULL && pwd[0] == '/' && stat(pwd, &s) != -1) { - dev = s.st_dev; - ino = s.st_ino; - if (stat(".", &s) != -1 && dev == s.st_dev && ino == s.st_ino) { - pwdlen = strlen(pwd); - if (pt) { - if (!size) { - errno = EINVAL; - return (NULL); - } - if (pwdlen + 1 > size) { - errno = ERANGE; - return (NULL); - } - } else if ((pt = malloc(pwdlen + 1)) == NULL) { - errno = ENOMEM; - return (NULL); - } - memmove(pt, pwd, pwdlen); - pt[pwdlen] = '\0'; - return (pt); - } - } - - return (getcwd_physical(pt, size)); -} - -/* - * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); - * - * 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(path, resolved) - const char *path; - char *resolved; -{ - struct stat sb; - int fd, n, rootd, serrno; - char *p, *q, wbuf[MAXPATHLEN]; - int symlinks = 0; - - /* Save the starting point. */ - if ((fd = open(".", O_RDONLY)) < 0) { - (void)strcpy(resolved, "."); - return (NULL); - } - - /* - * Find the dirname and basename from the path to be resolved. - * Change directory to the dirname component. - * lstat the basename part. - * if it is a symlink, read in the value and loop. - * if it is a directory, then change to that directory. - * get the current directory name and append the basename. - */ - (void)strncpy(resolved, path, MAXPATHLEN - 1); - resolved[MAXPATHLEN - 1] = '\0'; -loop: - q = strrchr(resolved, '/'); - if (q != NULL) { - p = q + 1; - if (q == resolved) - q = "/"; - else { - do { - --q; - } while (q > resolved && *q == '/'); - q[1] = '\0'; - q = resolved; - } - if (chdir(q) < 0) - goto err1; - } else - p = resolved; - - /* Deal with the last component. */ - if (lstat(p, &sb) == 0) { - if (S_ISLNK(sb.st_mode)) { - if (++symlinks > MAXSYMLINKS) { - errno = ELOOP; - goto err1; - } - n = readlink(p, resolved, MAXPATHLEN-1); - if (n < 0) - goto err1; - resolved[n] = '\0'; - goto loop; - } - if (S_ISDIR(sb.st_mode)) { - if (chdir(p) < 0) - goto err1; - p = ""; - } - } - - /* - * Save the last component name and get the full pathname of - * the current directory. - */ - (void)strcpy(wbuf, p); - - /* - * Call the inernal internal version of getcwd which - * does a physical search rather than using the $PWD short-cut - */ - if (getcwd_physical(resolved, MAXPATHLEN) == 0) - goto err1; - - /* - * Join the two strings together, ensuring that the right thing - * happens if the last component is empty, or the dirname is root. - */ - if (resolved[0] == '/' && resolved[1] == '\0') - rootd = 1; - else - rootd = 0; - - if (*wbuf) { - if (strlen(resolved) + strlen(wbuf) + (1-rootd) + 1 > - MAXPATHLEN) { - errno = ENAMETOOLONG; - goto err1; - } - if (rootd == 0) - (void)strcat(resolved, "/"); - (void)strcat(resolved, wbuf); - } - - /* Go back to where we came from. */ - if (fchdir(fd) < 0) { - serrno = errno; - goto err2; - } - - /* It's okay if the close fails, what's an fd more or less? */ - (void)close(fd); - return (resolved); - -err1: serrno = errno; - (void)fchdir(fd); -err2: (void)close(fd); - errno = serrno; - return (NULL); -} - -static char * -getcwd_physical(pt, size) - char *pt; - size_t size; -{ - register struct dirent *dp; - register DIR *dir; - register dev_t dev; - register ino_t ino; - register int first; - register char *bpt, *bup; + 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; + char *ept, *eup, *up, c; /* * If no buffer specified by the user, allocate one as necessary. @@ -262,12 +85,30 @@ getcwd_physical(pt, size) errno = EINVAL; return (NULL); } + if (size == 1) { + errno = ERANGE; + return (NULL); + } ept = pt + size; } else { if ((pt = malloc(ptsize = 1024 - 4)) == NULL) return (NULL); ept = pt + ptsize; } +#if !defined(__NETBSD_SYSCALLS) + if (__getcwd(pt, ept - pt) == 0) { + if (*pt != '/') { + bpt = pt; + ept = pt + strlen(pt) - 1; + while (bpt < ept) { + c = *bpt; + *bpt++ = *ept; + *ept-- = c; + } + } + return (pt); + } +#endif bpt = ept - 1; *bpt = '\0'; @@ -308,7 +149,7 @@ getcwd_physical(pt, size) * path to the beginning of the buffer, but it's always * been that way and stuff would probably break. */ - (void)bcopy(bpt, pt, ept - bpt); + bcopy(bpt, pt, ept - bpt); free(up); return (pt); } @@ -316,10 +157,10 @@ getcwd_physical(pt, size) /* * Build pointer to the parent directory, allocating memory * as necessary. Max length is 3 for "../", the largest - * possible component name, plus a trailing NULL. + * possible component name, plus a trailing NUL. */ if (bup + 3 + MAXNAMLEN + 1 >= eup) { - if ((up = realloc(up, upsize *= 2)) == NULL) + if ((up = reallocf(up, upsize *= 2)) == NULL) goto err; bup = up; eup = up + upsize; @@ -329,11 +170,12 @@ getcwd_physical(pt, size) *bup = '\0'; /* Open and stat parent directory. */ - if (!(dir = opendir(up)) || fstat(dirfd(dir), &s)) + 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 @@ -371,7 +213,7 @@ getcwd_physical(pt, size) * Check for length of the current name, preceding slash, * leading slash. */ - if (bpt - pt <= dp->d_namlen + (first ? 1 : 2)) { + if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { size_t len, off; if (!ptsize) { @@ -380,18 +222,19 @@ getcwd_physical(pt, size) } off = bpt - pt; len = ept - bpt; - if ((pt = realloc(pt, ptsize *= 2)) == NULL) + if ((pt = reallocf(pt, ptsize *= 2)) == NULL) goto err; bpt = pt + off; ept = pt + ptsize; - (void)bcopy(bpt, ept - len, len); + 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); + (void) closedir(dir); + dir = NULL; /* Truncate any file name. */ *bup = '\0'; @@ -407,8 +250,14 @@ notfound: 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); } diff --git a/gen/FreeBSD/getcwd.c.patch b/gen/FreeBSD/getcwd.c.patch new file mode 100644 index 0000000..d7515bf --- /dev/null +++ b/gen/FreeBSD/getcwd.c.patch @@ -0,0 +1,32 @@ +--- getcwd.c.orig Thu Jan 9 18:58:25 2003 ++++ getcwd.c Sat May 3 14:04:22 2003 +@@ -54,8 +54,6 @@ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +-extern int __getcwd(char *, size_t); +- + char * + getcwd(pt, size) + char *pt; +@@ -95,20 +93,6 @@ + return (NULL); + ept = pt + ptsize; + } +-#if !defined(__NETBSD_SYSCALLS) +- if (__getcwd(pt, ept - pt) == 0) { +- if (*pt != '/') { +- bpt = pt; +- ept = pt + strlen(pt) - 1; +- while (bpt < ept) { +- c = *bpt; +- *bpt++ = *ept; +- *ept-- = c; +- } +- } +- return (pt); +- } +-#endif + bpt = ept - 1; + *bpt = '\0'; + diff --git a/gen/gethostname.3 b/gen/FreeBSD/gethostname.3 similarity index 94% rename from gen/gethostname.3 rename to gen/FreeBSD/gethostname.3 index 9651d8d..567b6a6 100644 --- a/gen/gethostname.3 +++ b/gen/FreeBSD/gethostname.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/gethostname.3,v 1.11 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/gethostname.3,v 1.13 2002/12/19 09:40:21 ru Exp $ .\" .Dd June 4, 1993 .Dt GETHOSTNAME 3 @@ -48,18 +48,23 @@ .Ft int .Fn sethostname "const char *name" "int namelen" .Sh DESCRIPTION -.Fn Gethostname +The +.Fn gethostname +function returns the standard host name for the current processor, as previously set by .Fn sethostname . -The parameter +The .Fa namelen +argument specifies the size of the .Fa name array. The returned name is null-terminated unless insufficient space is provided. .Pp -.Fn Sethostname +The +.Fn sethostname +function sets the name of the host machine to be .Fa name , which has length @@ -76,7 +81,7 @@ The .Fa name or .Fa namelen -parameter gave an +argument gave an invalid address. .It Bq Er EPERM The caller tried to set the hostname and was not the super-user. @@ -95,5 +100,5 @@ This includes the trailing .Sh HISTORY The .Fn gethostname -function call appeared in +function appeared in .Bx 4.2 . diff --git a/gen/gethostname.c b/gen/FreeBSD/gethostname.c similarity index 66% rename from gen/gethostname.c rename to gen/FreeBSD/gethostname.c index 4f4c250..016a387 100644 --- a/gen/gethostname.c +++ b/gen/FreeBSD/gethostname.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,12 +31,16 @@ * 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.3 2002/03/22 21:52:05 obrien Exp $"); #include #include - -long +int gethostname(name, namelen) char *name; int namelen; diff --git a/gen/getlogin.c b/gen/FreeBSD/getlogin.c similarity index 58% rename from gen/getlogin.c rename to gen/FreeBSD/getlogin.c index e30eda6..5a5b42b 100644 --- a/gen/getlogin.c +++ b/gen/FreeBSD/getlogin.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,32 +31,80 @@ * 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.8 2002/03/29 22:43:41 markm Exp $"); #include +#include #include #include #include #include #include -#include +#include "namespace.h" +#include +#include "un-namespace.h" -int _logname_valid = 0; /* known to setlogin() */ +#include "libc_private.h" -char * -getlogin() -{ - static char *logname = NULL; +#define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&logname_mutex) +#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&logname_mutex) - if ( logname == NULL ) { - logname = malloc(MAXLOGNAME+1); - if ( logname == NULL ) - return NULL; - } +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, MAXLOGNAME) < 0) - return ((char *)NULL); +#ifdef __NETBSD_SYSCALLS + if (_getlogin(logname, sizeof(logname) - 1) < 0) { +#else + if (_getlogin(logname, sizeof(logname)) < 0) { +#endif + *status = errno; + return (NULL); + } _logname_valid = 1; } - return (*logname ? logname : (char *)NULL); + *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, int 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.3 b/gen/FreeBSD/getmntinfo.3 similarity index 96% rename from gen/getmntinfo.3 rename to gen/FreeBSD/getmntinfo.3 index 58c08b8..307d494 100644 --- a/gen/getmntinfo.3 +++ b/gen/FreeBSD/getmntinfo.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getmntinfo.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/getmntinfo.3,v 1.11 2001/10/01 16:08:51 ru Exp $ +.\" $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 @@ -60,7 +60,7 @@ The function passes its .Fa flags -parameter transparently to +argument transparently to .Xr getfsstat 2 . .Sh RETURN VALUES On successful completion, diff --git a/gen/getmntinfo.c b/gen/FreeBSD/getmntinfo.c similarity index 71% rename from gen/getmntinfo.c rename to gen/FreeBSD/getmntinfo.c index 9384328..383df1e 100644 --- a/gen/getmntinfo.c +++ b/gen/FreeBSD/getmntinfo.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 diff --git a/gen/getpagesize.3 b/gen/FreeBSD/getpagesize.3 similarity index 93% rename from gen/getpagesize.3 rename to gen/FreeBSD/getpagesize.3 index 8f4cad3..a8e57e1 100644 --- a/gen/getpagesize.3 +++ b/gen/FreeBSD/getpagesize.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getpagesize.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getpagesize.3,v 1.9 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getpagesize.3,v 1.11 2002/12/27 12:15:28 schweikh Exp $ .\" .Dd June 4, 1993 .Dt GETPAGESIZE 3 @@ -45,7 +45,9 @@ .Ft int .Fn getpagesize void .Sh DESCRIPTION -.Fn Getpagesize +The +.Fn getpagesize +function returns the number of bytes in a page. Page granularity is the granularity of many of the memory management calls. @@ -58,6 +60,6 @@ hardware page size. .Xr sbrk 2 .Sh HISTORY The -.Fn getpagesze -function call appeared in +.Fn getpagesize +function appeared in .Bx 4.2 . diff --git a/gen/getpagesize.c b/gen/FreeBSD/getpagesize.c similarity index 62% rename from gen/getpagesize.c rename to gen/FreeBSD/getpagesize.c index e84e50f..3c8881e 100644 --- a/gen/getpagesize.c +++ b/gen/FreeBSD/getpagesize.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,21 +31,36 @@ * 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], value; + int mib[2]; + static int value; size_t size; - mib[0] = CTL_HW; - mib[1] = HW_PAGESIZE; - size = sizeof value; - if (sysctl(mib, 2, &value, &size, NULL, 0) == -1) - return (-1); + 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/getpass.3 b/gen/FreeBSD/getpass.3 similarity index 96% rename from gen/getpass.3 rename to gen/FreeBSD/getpass.3 index 430a47e..f3317bd 100644 --- a/gen/getpass.3 +++ b/gen/FreeBSD/getpass.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getpass.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getpass.3,v 1.9 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/getpass.3,v 1.11 2001/11/22 09:48:54 ru Exp $ .\" .Dd June 4, 1993 .Dt GETPASS 3 @@ -72,7 +72,8 @@ function returns a pointer to the null terminated password. .It Pa /dev/tty .El .Sh SEE ALSO -.Xr crypt 3 +.Xr crypt 3 , +.Xr readpassphrase 3 .Sh HISTORY A .Fn getpass diff --git a/gen/FreeBSD/getprogname.3 b/gen/FreeBSD/getprogname.3 new file mode 100644 index 0000000..5ea703e --- /dev/null +++ b/gen/FreeBSD/getprogname.3 @@ -0,0 +1,94 @@ +.\" +.\" 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 , +.Xr setproctitle 3 +.Sh HISTORY +These functions first appeared in +.Nx 1.6 , +and made their way into +.Fx 4.4 . diff --git a/gen/FreeBSD/getprogname.c b/gen/FreeBSD/getprogname.c new file mode 100644 index 0000000..4be82e3 --- /dev/null +++ b/gen/FreeBSD/getprogname.c @@ -0,0 +1,17 @@ +#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 "un-namespace.h" + +#include "libc_private.h" + +__weak_reference(_getprogname, getprogname); + +const char * +_getprogname(void) +{ + + return (__progname); +} diff --git a/gen/FreeBSD/getprogname.c.patch b/gen/FreeBSD/getprogname.c.patch new file mode 100644 index 0000000..54f9906 --- /dev/null +++ b/gen/FreeBSD/getprogname.c.patch @@ -0,0 +1,11 @@ +--- getprogname.c.orig Mon Apr 28 15:05:02 2003 ++++ getprogname.c Sat May 3 14:04:57 2003 +@@ -3,6 +3,8 @@ + + #include "namespace.h" + #include ++#include ++#define __progname (*_NSGetProgname()) + #include "un-namespace.h" + + #include "libc_private.h" diff --git a/gen/isatty.c b/gen/FreeBSD/isatty.c similarity index 63% rename from gen/isatty.c rename to gen/FreeBSD/isatty.c index d0d7a57..d16a963 100644 --- a/gen/isatty.c +++ b/gen/FreeBSD/isatty.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -63,7 +44,9 @@ int isatty(fd) int fd; { + int retval; struct termios t; - return(tcgetattr(fd, &t) != -1); + retval = (tcgetattr(fd, &t) != -1); + return(retval); } diff --git a/gen/FreeBSD/isatty.c.patch b/gen/FreeBSD/isatty.c.patch new file mode 100644 index 0000000..c7bc48f --- /dev/null +++ b/gen/FreeBSD/isatty.c.patch @@ -0,0 +1,24 @@ +--- isatty.c.orig Thu Jan 31 16:57:29 2002 ++++ isatty.c Sun May 18 00:50:20 2003 +@@ -39,14 +39,19 @@ + + #include + #include ++#include ++#include + + int + isatty(fd) + int fd; + { +- int retval; ++ int retval, type; + struct termios t; + +- retval = (tcgetattr(fd, &t) != -1); ++ if(ioctl(fd, FIODTYPE, &type) != -1) ++ retval = (type == D_TTY); ++ else ++ retval = (tcgetattr(fd, &t) != -1); + return(retval); + } diff --git a/gen/jrand48.c b/gen/FreeBSD/jrand48.c similarity index 83% rename from gen/jrand48.c rename to gen/FreeBSD/jrand48.c index 051d5a6..f47bf2a 100644 --- a/gen/jrand48.c +++ b/gen/FreeBSD/jrand48.c @@ -11,6 +11,9 @@ * 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 diff --git a/gen/lcong48.c b/gen/FreeBSD/lcong48.c similarity index 87% rename from gen/lcong48.c rename to gen/FreeBSD/lcong48.c index f13826b..8b11e08 100644 --- a/gen/lcong48.c +++ b/gen/FreeBSD/lcong48.c @@ -11,6 +11,9 @@ * 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" extern unsigned short _rand48_seed[3]; diff --git a/gen/lockf.3 b/gen/FreeBSD/lockf.3 similarity index 98% rename from gen/lockf.3 rename to gen/FreeBSD/lockf.3 index 83f7818..7041fe2 100644 --- a/gen/lockf.3 +++ b/gen/FreeBSD/lockf.3 @@ -34,7 +34,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/lockf.3,v 1.10 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/lockf.3,v 1.11 2002/12/18 10:13:54 ru Exp $ .\" .Dd December 19, 1997 .Dt LOCKF 3 @@ -171,6 +171,7 @@ locked region is unlocked would cause a deadlock and fails with an .Er EDEADLK error. .Pp +The .Fn lockf , .Xr fcntl 2 and @@ -182,7 +183,9 @@ Blocking on a section is interrupted by any signal. .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 diff --git a/gen/lockf.c b/gen/FreeBSD/lockf.c similarity index 89% rename from gen/lockf.c rename to gen/FreeBSD/lockf.c index da94a3f..375b2ce 100644 --- a/gen/lockf.c +++ b/gen/FreeBSD/lockf.c @@ -1,5 +1,3 @@ -/* $NetBSD: lockf.c,v 1.1 1997/12/20 20:23:18 kleink Exp $ */ - /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -34,18 +32,17 @@ * CONTRACT, STRICT LIABILITY, OR TORT (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.c,v 1.5 2000/01/27 23:06:17 jasone Exp $ */ -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[]= - "$FreeBSD: src/lib/libc/gen/lockf.c,v 1.5 2000/01/27 23:06:17 jasone Exp $"; -#endif +/* $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 $"); +#include "namespace.h" #include #include #include +#include "un-namespace.h" int lockf(filedes, function, size) @@ -75,7 +72,7 @@ lockf(filedes, function, size) break; case F_TEST: fl.l_type = F_WRLCK; - if (fcntl(filedes, F_GETLK, &fl) == -1) + if (_fcntl(filedes, F_GETLK, &fl) == -1) return (-1); if (fl.l_type == F_UNLCK || fl.l_pid == getpid()) return (0); @@ -88,5 +85,5 @@ lockf(filedes, function, size) /* NOTREACHED */ } - return (fcntl(filedes, cmd, &fl)); + return (_fcntl(filedes, cmd, &fl)); } diff --git a/gen/lrand48.c b/gen/FreeBSD/lrand48.c similarity index 84% rename from gen/lrand48.c rename to gen/FreeBSD/lrand48.c index a3d0111..948b923 100644 --- a/gen/lrand48.c +++ b/gen/FreeBSD/lrand48.c @@ -11,6 +11,9 @@ * 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" extern unsigned short _rand48_seed[3]; diff --git a/gen/mrand48.c b/gen/FreeBSD/mrand48.c similarity index 84% rename from gen/mrand48.c rename to gen/FreeBSD/mrand48.c index b23db51..f65ed77 100644 --- a/gen/mrand48.c +++ b/gen/FreeBSD/mrand48.c @@ -11,6 +11,9 @@ * 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" extern unsigned short _rand48_seed[3]; diff --git a/gen/nice.3 b/gen/FreeBSD/nice.3 similarity index 100% rename from gen/nice.3 rename to gen/FreeBSD/nice.3 diff --git a/gen/nice.c b/gen/FreeBSD/nice.c similarity index 67% rename from gen/nice.c rename to gen/FreeBSD/nice.c index 4ed41f7..453caa7 100644 --- a/gen/nice.c +++ b/gen/FreeBSD/nice.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,12 +31,18 @@ * 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 +#include + /* * Backwards compatible nice. */ diff --git a/gen/nrand48.c b/gen/FreeBSD/nrand48.c similarity index 83% rename from gen/nrand48.c rename to gen/FreeBSD/nrand48.c index 6c54065..3a21c3f 100644 --- a/gen/nrand48.c +++ b/gen/FreeBSD/nrand48.c @@ -11,6 +11,9 @@ * 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 diff --git a/gen/opendir.c b/gen/FreeBSD/opendir.c similarity index 70% rename from gen/opendir.c rename to gen/FreeBSD/opendir.c index a0b9e57..b0de975 100644 --- a/gen/opendir.c +++ b/gen/FreeBSD/opendir.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,7 +31,13 @@ * 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.19 2003/01/04 00:18:50 tjr Exp $"); +#include "namespace.h" #include #include #include @@ -64,39 +46,68 @@ #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(const char *name, int flags) +DIR * +__opendir2(name, flags) + const char *name; + int flags; { DIR *dirp; int fd; int incr; + int saved_errno; int unionstack; struct stat statb; - if ((fd = open(name, O_RDONLY)) == -1) + /* + * stat() before _open() because opening of special files may be + * harmful. _fstat() after open because the file may have changed. + */ + if (stat(name, &statb) != 0) return (NULL); - if (fstat(fd, &statb) || !S_ISDIR(statb.st_mode)) { + if (!S_ISDIR(statb.st_mode)) { errno = ENOTDIR; - close(fd); return (NULL); } - if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || - (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) { - close(fd); + if ((fd = _open(name, O_RDONLY | O_NONBLOCK)) == -1) return (NULL); + dirp = NULL; + if (_fstat(fd, &statb) != 0) + goto fail; + if (!S_ISDIR(statb.st_mode)) { + errno = ENOTDIR; + goto fail; } + if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || + (dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) + goto fail; + + dirp->dd_td = (void *)dirp + sizeof(DIR); + LIST_INIT(&dirp->dd_td->td_locq); + dirp->dd_td->td_loccnt = 0; /* - * If CLBYTES is an exact multiple of DIRBLKSIZ, use a CLBYTES - * buffer that it cluster boundary aligned. + * 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() + * trades to user space to be done by _getdirentries(). */ - if ((CLBYTES % DIRBLKSIZ) == 0) - incr = CLBYTES; - else + incr = getpagesize(); + if ((incr % DIRBLKSIZ) != 0) incr = DIRBLKSIZ; /* @@ -105,12 +116,10 @@ DIR *__opendir2(const char *name, int flags) if (flags & DTF_NODUP) { struct statfs sfb; - if (fstatfs(fd, &sfb) < 0) { - free(dirp); - close(fd); - return (NULL); - } - unionstack = (!strcmp(sfb.f_fstypename, "union") || (sfb.f_flags & MNT_UNION)); + if (_fstatfs(fd, &sfb) < 0) + goto fail; + unionstack = !strcmp(sfb.f_fstypename, "union") + || (sfb.f_flags & MNT_UNION); } else { unionstack = 0; } @@ -134,21 +143,18 @@ DIR *__opendir2(const char *name, int flags) do { /* * Always make at least DIRBLKSIZ bytes - * available to getdirentries + * available to _getdirentries */ if (space < DIRBLKSIZ) { space += incr; len += incr; - buf = realloc(buf, len); - if (buf == NULL) { - free(dirp); - close(fd); - return (NULL); - } + buf = reallocf(buf, len); + if (buf == NULL) + goto fail; ddptr = buf + (len - space); } - n = getdirentries(fd, ddptr, space, &dirp->dd_seek); + n = _getdirentries(fd, ddptr, space, &dirp->dd_seek); if (n > 0) { ddptr += n; space -= n; @@ -166,10 +172,12 @@ DIR *__opendir2(const char *name, int flags) * which has also been read -- see fts.c. */ if (flags & DTF_REWIND) { - (void) close(fd); - if ((fd = open(name, O_RDONLY)) == -1) { + (void)_close(fd); + if ((fd = _open(name, O_RDONLY)) == -1) { + saved_errno = errno; free(buf); free(dirp); + errno = saved_errno; return (NULL); } } @@ -194,7 +202,7 @@ DIR *__opendir2(const char *name, int flags) struct dirent *dp; dp = (struct dirent *) ddptr; - if ((int)dp & 03) + if ((long)dp & 03L) break; if ((dp->d_reclen <= 0) || (dp->d_reclen > (ddeptr + 1 - ddptr))) @@ -251,11 +259,8 @@ DIR *__opendir2(const char *name, int flags) } else { dirp->dd_len = incr; dirp->dd_buf = malloc(dirp->dd_len); - if (dirp->dd_buf == NULL) { - free(dirp); - close (fd); - return (NULL); - } + if (dirp->dd_buf == NULL) + goto fail; dirp->dd_seek = 0; flags &= ~DTF_REWIND; } @@ -263,6 +268,7 @@ DIR *__opendir2(const char *name, int flags) dirp->dd_loc = 0; dirp->dd_fd = fd; dirp->dd_flags = flags; + dirp->dd_lock = NULL; /* * Set up seek point for rewinddir. @@ -270,12 +276,11 @@ DIR *__opendir2(const char *name, int flags) dirp->dd_rewind = telldir(dirp); return (dirp); -} -/* - * Open a directory. - */ -DIR *opendir(const char *name) -{ - return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); +fail: + saved_errno = errno; + free(dirp); + (void)_close(fd); + errno = saved_errno; + return (NULL); } diff --git a/gen/FreeBSD/opendir.c.patch b/gen/FreeBSD/opendir.c.patch new file mode 100644 index 0000000..86368f5 --- /dev/null +++ b/gen/FreeBSD/opendir.c.patch @@ -0,0 +1,19 @@ +--- opendir.c.orig Fri Jan 3 16:18:50 2003 ++++ opendir.c Sat May 3 15:00:52 2003 +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include "un-namespace.h" + + #include "telldir.h" +@@ -268,7 +269,7 @@ + dirp->dd_loc = 0; + dirp->dd_fd = fd; + dirp->dd_flags = flags; +- dirp->dd_lock = NULL; ++ dirp->dd_lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + + /* + * Set up seek point for rewinddir. diff --git a/gen/pause.3 b/gen/FreeBSD/pause.3 similarity index 100% rename from gen/pause.3 rename to gen/FreeBSD/pause.3 diff --git a/gen/pause.c b/gen/FreeBSD/pause.c similarity index 64% rename from gen/pause.c rename to gen/FreeBSD/pause.c index fceceba..4f56289 100644 --- a/gen/pause.c +++ b/gen/FreeBSD/pause.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * SUCH DAMAGE. */ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.6 2002/02/01 00:57:29 obrien Exp $"); #include #include @@ -63,8 +44,9 @@ * Backwards compatible pause. */ int -pause() +__pause() { - return sigpause(sigblock(0L)); } +__weak_reference(__pause, pause); +__weak_reference(__pause, _pause); diff --git a/gen/popen.3 b/gen/FreeBSD/popen.3 similarity index 98% rename from gen/popen.3 rename to gen/FreeBSD/popen.3 index 757531b..4831835 100644 --- a/gen/popen.3 +++ b/gen/FreeBSD/popen.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)popen.3 8.2 (Berkeley) 5/3/95 -.\" $FreeBSD: src/lib/libc/gen/popen.3,v 1.14 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/popen.3,v 1.15 2003/01/03 05:21:59 tjr Exp $ .\" .Dd May 3, 1995 .Dt POPEN 3 @@ -184,7 +184,7 @@ The only hint is an exit status of 127. .Pp The .Fn popen -argument +function always calls .Xr sh 1 , never calls diff --git a/gen/popen.c b/gen/FreeBSD/popen.c similarity index 67% rename from gen/popen.c rename to gen/FreeBSD/popen.c index 19d9272..0ed5657 100644 --- a/gen/popen.c +++ b/gen/FreeBSD/popen.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -58,9 +34,15 @@ * 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 #include @@ -69,16 +51,22 @@ #include #include #include -#include +#include +#include "un-namespace.h" +#include "libc_private.h" -#define environ *(_NSGetEnviron()) +extern char **environ; static struct pid { struct pid *next; FILE *fp; pid_t pid; -} *pidlist; - +} *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; @@ -89,11 +77,13 @@ popen(command, type) char *argv[4]; struct pid *p; + /* + * Lite2 introduced two-way popen() pipes using _socketpair(). + * FreeBSD's pipe() is bidirectional, so we use that. + */ if (strchr(type, '+')) { 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]) @@ -103,8 +93,8 @@ popen(command, type) return (NULL); if ((cur = malloc(sizeof(struct pid))) == NULL) { - (void)close(pdes[0]); - (void)close(pdes[1]); + (void)_close(pdes[0]); + (void)_close(pdes[1]); return (NULL); } @@ -113,10 +103,12 @@ popen(command, type) argv[2] = (char *)command; argv[3] = NULL; + THREAD_LOCK(); switch (pid = vfork()) { case -1: /* Error. */ - (void)close(pdes[0]); - (void)close(pdes[1]); + THREAD_UNLOCK(); + (void)_close(pdes[0]); + (void)_close(pdes[1]); free(cur); return (NULL); /* NOTREACHED */ @@ -130,43 +122,46 @@ popen(command, type) * the compiler is free to corrupt all the local * variables. */ - (void)close(pdes[0]); + (void)_close(pdes[0]); if (pdes[1] != STDOUT_FILENO) { - (void)dup2(pdes[1], STDOUT_FILENO); - (void)close(pdes[1]); + (void)_dup2(pdes[1], STDOUT_FILENO); + (void)_close(pdes[1]); if (twoway) - (void)dup2(STDOUT_FILENO, STDIN_FILENO); + (void)_dup2(STDOUT_FILENO, STDIN_FILENO); } else if (twoway && (pdes[1] != STDIN_FILENO)) - (void)dup2(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]); + (void)_dup2(pdes[0], STDIN_FILENO); + (void)_close(pdes[0]); } + (void)_close(pdes[1]); + } for (p = pidlist; p; p = p->next) { - (void)close(fileno(p->fp)); + (void)_close(fileno(p->fp)); } - execve(_PATH_BSHELL, argv, environ); + _execve(_PATH_BSHELL, argv, environ); _exit(127); /* NOTREACHED */ } + THREAD_UNLOCK(); /* Parent; assume fdopen can't fail. */ if (*type == 'r') { iop = fdopen(pdes[0], type); - (void)close(pdes[1]); + (void)_close(pdes[1]); } else { iop = fdopen(pdes[1], type); - (void)close(pdes[0]); + (void)_close(pdes[0]); } /* Link into list of file descriptors. */ cur->fp = iop; - cur->pid = pid; + cur->pid = pid; + THREAD_LOCK(); cur->next = pidlist; pidlist = cur; + THREAD_UNLOCK(); return (iop); } @@ -180,29 +175,34 @@ int pclose(iop) FILE *iop; { - register struct pid *cur, *last; + struct pid *cur, *last; int pstat; pid_t pid; - /* Find the appropriate file pointer. */ + /* + * 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) + 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); + pid = _wait4(cur->pid, &pstat, 0, (struct rusage *)0); } while (pid == -1 && errno == EINTR); - /* Remove the entry from the linked list. */ - if (last == NULL) - pidlist = cur->next; - else - last->next = cur->next; free(cur); - + return (pid == -1 ? -1 : pstat); } diff --git a/gen/FreeBSD/popen.c.patch b/gen/FreeBSD/popen.c.patch new file mode 100644 index 0000000..a5e07fc --- /dev/null +++ b/gen/FreeBSD/popen.c.patch @@ -0,0 +1,12 @@ +--- popen.c.orig Fri Jan 3 16:15:15 2003 ++++ popen.c Sat May 3 14:05:13 2003 +@@ -55,7 +55,8 @@ + #include "un-namespace.h" + #include "libc_private.h" + +-extern char **environ; ++#include ++#define environ (*_NSGetEnviron()) + + static struct pid { + struct pid *next; diff --git a/gen/FreeBSD/pselect.3 b/gen/FreeBSD/pselect.3 new file mode 100644 index 0000000..4b12fb7 --- /dev/null +++ b/gen/FreeBSD/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 sys/select.h +.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" +.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 exceptfds +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 newsigmask +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/FreeBSD/pselect.3.patch b/gen/FreeBSD/pselect.3.patch new file mode 100644 index 0000000..33bbca8 --- /dev/null +++ b/gen/FreeBSD/pselect.3.patch @@ -0,0 +1,11 @@ +--- pselect.3.orig Wed Dec 18 02:13:54 2002 ++++ pselect.3 Fri May 2 16:46:17 2003 +@@ -37,7 +37,7 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS +-.In sys/select.h ++.In unistd.h + .Ft int + .Fo pselect + .Fa "int nfds" diff --git a/gen/FreeBSD/pselect.c b/gen/FreeBSD/pselect.c new file mode 100644 index 0000000..13b2553 --- /dev/null +++ b/gen/FreeBSD/pselect.c @@ -0,0 +1,78 @@ +/* + * 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. + */ + +#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 "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/FreeBSD/pselect.c.patch b/gen/FreeBSD/pselect.c.patch new file mode 100644 index 0000000..3195aeb --- /dev/null +++ b/gen/FreeBSD/pselect.c.patch @@ -0,0 +1,13 @@ +--- pselect.c.orig Sat Oct 12 09:13:37 2002 ++++ pselect.c Fri May 16 14:11:39 2003 +@@ -31,8 +31,10 @@ + __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 diff --git a/gen/psignal.3 b/gen/FreeBSD/psignal.3 similarity index 96% rename from gen/psignal.3 rename to gen/FreeBSD/psignal.3 index 67bed20..02013a4 100644 --- a/gen/psignal.3 +++ b/gen/FreeBSD/psignal.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)psignal.3 8.2 (Berkeley) 2/27/95 -.\" $FreeBSD: src/lib/libc/gen/psignal.3,v 1.15 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/psignal.3,v 1.16 2002/12/30 21:18:02 schweikh Exp $ .\" .Dd February 27, 1995 .Dt PSIGNAL 3 @@ -68,7 +68,7 @@ and returns a pointer to the corresponding message string. .Pp The .Fn psignal -function accepts an signal number argument +function accepts a signal number argument .Fa sig and writes it to the standard error. If the argument diff --git a/gen/FreeBSD/psignal.c b/gen/FreeBSD/psignal.c new file mode 100644 index 0000000..832e04b --- /dev/null +++ b/gen/FreeBSD/psignal.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/raise.3 b/gen/FreeBSD/raise.3 similarity index 100% rename from gen/raise.3 rename to gen/FreeBSD/raise.3 diff --git a/gen/FreeBSD/raise.c b/gen/FreeBSD/raise.c new file mode 100644 index 0000000..d7ef43e --- /dev/null +++ b/gen/FreeBSD/raise.c @@ -0,0 +1,48 @@ +/*- + * 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[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/raise.c,v 1.3 2002/03/22 21:52:05 obrien Exp $"); + +#include +#include + +int +raise(s) + int s; +{ + return(kill(getpid(), s)); +} diff --git a/gen/rand48.3 b/gen/FreeBSD/rand48.3 similarity index 94% rename from gen/rand48.3 rename to gen/FreeBSD/rand48.3 index 08aafec..59bab77 100644 --- a/gen/rand48.3 +++ b/gen/FreeBSD/rand48.3 @@ -10,7 +10,7 @@ .\" to anyone/anything when using this software. .\" .\" @(#)rand48.3 V1.0 MB 8 Oct 1993 -.\" $FreeBSD: src/lib/libc/gen/rand48.3,v 1.13 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/rand48.3,v 1.15 2002/12/19 09:40:21 ru Exp $ .\" .Dd October 8, 1993 .Dt RAND48 3 @@ -65,33 +65,41 @@ r(n) is called the seed of the random number generator. For all 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 @@ -106,7 +114,9 @@ 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 , @@ -117,7 +127,9 @@ 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 , @@ -128,7 +140,9 @@ 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 @@ -149,7 +163,7 @@ and the seed used in .Fn lrand48 , and .Fn mrand48 . -An array of 7 shorts is passed as parameter; the first three shorts are +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. diff --git a/gen/rand48.h b/gen/FreeBSD/rand48.h similarity index 86% rename from gen/rand48.h rename to gen/FreeBSD/rand48.h index 5b9f87d..0a3d83d 100644 --- a/gen/rand48.h +++ b/gen/FreeBSD/rand48.h @@ -9,6 +9,8 @@ * 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_ @@ -17,7 +19,7 @@ #include #include -void _dorand48 __P((unsigned short[3])); +void _dorand48(unsigned short[3]); #define RAND48_SEED_0 (0x330e) #define RAND48_SEED_1 (0xabcd) diff --git a/gen/readdir.c b/gen/FreeBSD/readdir.c similarity index 63% rename from gen/readdir.c rename to gen/FreeBSD/readdir.c index e8bd11b..fa0438c 100644 --- a/gen/readdir.c +++ b/gen/FreeBSD/readdir.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,18 +31,30 @@ * 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 "un-namespace.h" + +#include "libc_private.h" /* * get next entry in a directory. */ struct dirent * -readdir(dirp) - register DIR *dirp; +_readdir_unlocked(dirp) + DIR *dirp; { - register struct dirent *dp; + struct dirent *dp; for (;;) { if (dirp->dd_loc >= dirp->dd_size) { @@ -75,13 +63,13 @@ readdir(dirp) dirp->dd_loc = 0; } if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { - dirp->dd_size = getdirentries(dirp->dd_fd, + dirp->dd_size = _getdirentries(dirp->dd_fd, dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); if (dirp->dd_size <= 0) return (NULL); } dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); - if ((int)dp & 03) /* bogus pointer check */ + if ((long)dp & 03L) /* bogus pointer check */ return (NULL); if (dp->d_reclen <= 0 || dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) @@ -94,3 +82,53 @@ readdir(dirp) 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/FreeBSD/readpassphrase.3 b/gen/FreeBSD/readpassphrase.3 new file mode 100644 index 0000000..ea143ec --- /dev/null +++ b/gen/FreeBSD/readpassphrase.3 @@ -0,0 +1,191 @@ +.\" $OpenBSD: readpassphrase.3,v 1.7 2001/12/15 15:37:51 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. +.\" +.\" $FreeBSD: src/lib/libc/gen/readpassphrase.3,v 1.6 2002/12/27 12:15:28 schweikh Exp $ +.\" +.Dd December 7, 2001 +.Dt READPASSPHRASE 3 +.Os +.Sh NAME +.Nm readpassphrase +.Nd get a passphrase from the user +.Sh SYNOPSIS +.In readpassphrase.h +.Ft "char *" +.Fn readpassphrase "const char *prompt" "char *buf" "size_t bufsiz" "int flags" +.Sh DESCRIPTION +The +.Fn readpassphrase +function displays a prompt to, and reads in a passphrase from, +.Pa /dev/tty . +If this file is inaccessible +and the +.Dv RPP_REQUIRE_TTY +flag is not set, +.Fn readpassphrase +displays the prompt on the standard error output and reads from the standard +input. +In this case it is generally not possible to turn off echo. +.Pp +Up to +.Fa bufsiz +\- 1 characters (one is for the +.Dv NUL ) +are read into the provided buffer +.Fa buf . +Any additional +characters and the terminating newline (or return) character are discarded. +.Pp +The +.Fn readpassphrase +function +takes the following optional +.Fa flags : +.Pp +.Bl -tag -width ".Dv RPP_REQUIRE_TTY" -compact +.It Dv RPP_ECHO_OFF +turn off echo (default behavior) +.It Dv RPP_ECHO_ON +leave echo on +.It Dv RPP_REQUIRE_TTY +fail if there is no tty +.It Dv RPP_FORCELOWER +force input to lower case +.It Dv RPP_FORCEUPPER +force input to upper case +.It Dv RPP_SEVENBIT +strip the high bit from input +.El +.Pp +The calling process should zero the passphrase as soon as possible to +avoid leaving the cleartext passphrase visible in the process's address +space. +.Sh RETURN VALUES +Upon successful completion, +.Fn readpassphrase +returns a pointer to the null-terminated passphrase. +If an error is encountered, the terminal state is restored and +a +.Dv NULL +pointer is returned. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINTR +The +.Fn readpassphrase +function was interrupted by a signal. +.It Bq Er EINVAL +The +.Fa bufsiz +argument was zero. +.It Bq Er EIO +The process is a member of a background process attempting to read +from its controlling terminal, the process is ignoring or blocking +the +.Dv SIGTTIN +signal or the process group is orphaned. +.It Bq Er EMFILE +The process has already reached its limit for open file descriptors. +.It Bq Er ENFILE +The system file table is full. +.It Bq Er ENOTTY +There is no controlling terminal and the +.Dv RPP_REQUIRE_TTY +flag was specified. +.El +.Sh EXAMPLES +The following code fragment will read a passphrase from +.Pa /dev/tty +into the buffer +.Fa passbuf . +.Bd -literal -offset indent +char passbuf[1024]; + +\&... + +if (readpassphrase("Response: ", passbuf, sizeof(passbuf), + RPP_REQUIRE_TTY) == NULL) + errx(1, "unable to read passphrase"); + +if (compare(transform(passbuf), epass) != 0) + errx(1, "bad passphrase"); + +\&... + +memset(passbuf, 0, sizeof(passbuf)); +.Ed +.Sh SIGNALS +The +.Fn readpassphrase +function +will catch the following signals: +.Pp +.Bl -tag -compact +.It Dv SIGINT +.It Dv SIGHUP +.It Dv SIGQUIT +.It Dv SIGTERM +.It Dv SIGTSTP +.It Dv SIGTTIN +.It Dv SIGTTOU +.El +.Pp +When one of the above signals is intercepted, terminal echo will +be restored if it had previously been turned off. +If a signal handler was installed for the signal when +.Fn readpassphrase +was called that handler is then executed. +If no handler was previously installed for the signal then the +default action is taken as per +.Xr sigaction 2 . +.Pp +The +.Dv SIGTSTP , SIGTTIN , +and +.Dv SIGTTOU +signals (stop signal generated from keyboard or due to terminal I/O +from a background process) are treated specially. +When the process is resumed after it has been stopped, +.Fn readpassphrase +will reprint the prompt and the user may then enter a passphrase. +.Sh FILES +.Bl -tag -width ".Pa /dev/tty" -compact +.It Pa /dev/tty +.El +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr getpass 3 +.Sh STANDARDS +The +.Fn readpassphrase +function is an +extension and should not be used if portability is desired. +.Sh HISTORY +The +.Fn readpassphrase +function first appeared in +.Ox 2.9 . diff --git a/gen/FreeBSD/readpassphrase.c b/gen/FreeBSD/readpassphrase.c new file mode 100644 index 0000000..d100be4 --- /dev/null +++ b/gen/FreeBSD/readpassphrase.c @@ -0,0 +1,178 @@ +/* $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 "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; + + /* 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(ch)) { + if ((flags & RPP_FORCELOWER)) + ch = tolower(ch); + if ((flags & RPP_FORCEUPPER)) + ch = toupper(ch); + } + *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/rewinddir.c b/gen/FreeBSD/rewinddir.c similarity index 65% rename from gen/rewinddir.c rename to gen/FreeBSD/rewinddir.c index 7eb5872..dae75cc 100644 --- a/gen/rewinddir.c +++ b/gen/FreeBSD/rewinddir.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,10 +31,17 @@ * 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; diff --git a/gen/scandir.3 b/gen/FreeBSD/scandir.3 similarity index 93% rename from gen/scandir.3 rename to gen/FreeBSD/scandir.3 index f2a24e6..b76eff8 100644 --- a/gen/scandir.3 +++ b/gen/FreeBSD/scandir.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)scandir.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.7 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/scandir.3,v 1.8 2002/12/19 09:40:21 ru Exp $ .\" .Dd June 4, 1993 .Dt SCANDIR 3 @@ -64,7 +64,7 @@ referenced by .Pp The .Fa select -parameter is a pointer to a user supplied subroutine which is called by +argument is a pointer to a user supplied subroutine which is called by .Fn scandir to select which entries are to be included in the array. The select routine is passed a @@ -76,7 +76,7 @@ is null, then all the directory entries will be included. .Pp The .Fa compar -parameter is a pointer to a user supplied subroutine which is passed to +argument is a pointer to a user supplied subroutine which is passed to .Xr qsort 3 to sort the completed array. If this pointer is null, the array is not sorted. @@ -86,7 +86,7 @@ The function is a routine which can be used for the .Fa compar -parameter to sort the array alphabetically. +argument to sort the array alphabetically. .Pp The memory allocated for the array can be deallocated with .Xr free 3 , diff --git a/gen/scandir.c b/gen/FreeBSD/scandir.c similarity index 69% rename from gen/scandir.c rename to gen/FreeBSD/scandir.c index 7da9469..cf79bce 100644 --- a/gen/scandir.c +++ b/gen/FreeBSD/scandir.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -63,11 +44,13 @@ * 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 @@ -84,30 +67,29 @@ int scandir(dirname, namelist, select, dcomp) const char *dirname; struct dirent ***namelist; - int (*select) __P((struct dirent *)); - int (*dcomp) __P((const void *, const void *)); + int (*select)(struct dirent *); + int (*dcomp)(const void *, const void *); { - register struct dirent *d, *p, **names; - register size_t nitems; + 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) - 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. + * 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) - return(-1); + goto fail; - nitems = 0; while ((d = readdir(dirp)) != NULL) { if (select != NULL && !(*select)(d)) continue; /* just selected names */ @@ -116,8 +98,9 @@ scandir(dirname, namelist, select, dcomp) */ p = (struct dirent *)malloc(DIRSIZ(d)); if (p == NULL) - return(-1); - p->d_ino = d->d_ino; + 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); @@ -125,22 +108,33 @@ scandir(dirname, namelist, select, dcomp) * Check to make sure the array has space left and * realloc the maximum size. */ - if (++nitems >= arraysz) { - if (fstat(dirp->dd_fd, &stb) < 0) - return(-1); /* just might have grown */ - arraysz = stb.st_size / 12; - names = (struct dirent **)realloc((char *)names, - arraysz * sizeof(struct dirent *)); - if (names == NULL) - return(-1); + 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-1] = p; + 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; } /* diff --git a/gen/seed48.c b/gen/FreeBSD/seed48.c similarity index 89% rename from gen/seed48.c rename to gen/FreeBSD/seed48.c index 258c4ba..94167a7 100644 --- a/gen/seed48.c +++ b/gen/FreeBSD/seed48.c @@ -11,6 +11,9 @@ * 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" extern unsigned short _rand48_seed[3]; diff --git a/gen/seekdir.c b/gen/FreeBSD/seekdir.c similarity index 66% rename from gen/seekdir.c rename to gen/FreeBSD/seekdir.c index 29949ed..5385819 100644 --- a/gen/seekdir.c +++ b/gen/FreeBSD/seekdir.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,9 +31,20 @@ * 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. @@ -68,6 +55,9 @@ 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/FreeBSD/sethostname.c b/gen/FreeBSD/sethostname.c new file mode 100644 index 0000000..3a15727 --- /dev/null +++ b/gen/FreeBSD/sethostname.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/setmode.3 b/gen/FreeBSD/setmode.3 similarity index 97% rename from gen/setmode.3 rename to gen/FreeBSD/setmode.3 index 07909bd..ac41f4c 100644 --- a/gen/setmode.3 +++ b/gen/FreeBSD/setmode.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setmode.3 8.2 (Berkeley) 4/28/95 -.\" $FreeBSD: src/lib/libc/gen/setmode.3,v 1.8.2.3 2001/12/14 18:33:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/setmode.3,v 1.11 2001/10/01 16:08:51 ru Exp $ .\" .Dd April 28, 1995 .Dt SETMODE 3 diff --git a/gen/setmode.c b/gen/FreeBSD/setmode.c similarity index 91% rename from gen/setmode.c rename to gen/FreeBSD/setmode.c index 181af06..3e4a6ee 100644 --- a/gen/setmode.c +++ b/gen/FreeBSD/setmode.c @@ -35,13 +35,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -#if 0 static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94"; -#endif -static const char rcsid[] = - "$FreeBSD: src/lib/libc/gen/setmode.c,v 1.5.2.1 2001/03/05 09:34:10 obrien Exp $"; #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 @@ -49,10 +48,12 @@ static const char rcsid[] = #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 */ @@ -69,10 +70,10 @@ typedef struct bitcmd { #define CMD2_OBITS 0x08 #define CMD2_UBITS 0x10 -static BITCMD *addcmd __P((BITCMD *, int, int, int, u_int)); -static void compress_mode __P((BITCMD *)); +static BITCMD *addcmd(BITCMD *, int, int, int, u_int); +static void compress_mode(BITCMD *); #ifdef SETMODE_DEBUG -static void dumpmode __P((BITCMD *)); +static void dumpmode(BITCMD *); #endif /* @@ -83,13 +84,13 @@ static void dumpmode __P((BITCMD *)); */ mode_t getmode(bbox, omode) - void *bbox; + const void *bbox; mode_t omode; { - register BITCMD *set; - register mode_t clrval, newmode, value; + const BITCMD *set; + mode_t clrval, newmode, value; - set = (BITCMD *)bbox; + set = (const BITCMD *)bbox; newmode = omode; for (value = 0;; set++) switch(set->cmd) { @@ -153,11 +154,15 @@ common: if (set->cmd2 & CMD2_CLR) { #define ADDCMD(a, b, c, d) \ if (set >= endset) { \ - register BITCMD *newset; \ + BITCMD *newset; \ setlen += SET_LEN_INCR; \ newset = realloc(saveset, sizeof(BITCMD) * setlen); \ - if (!saveset) \ + if (!newset) { \ + if (saveset) \ + free(saveset); \ + saveset = NULL; \ return (NULL); \ + } \ set = newset + (set - saveset); \ saveset = newset; \ endset = newset + (setlen - 2); \ @@ -168,14 +173,15 @@ common: if (set->cmd2 & CMD2_CLR) { void * setmode(p) - register char *p; + const char *p; { - register int perm, who; - register char op; + 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); @@ -187,10 +193,10 @@ setmode(p) * as best we can. */ sigfillset(&sigset); - (void)sigprocmask(SIG_BLOCK, &sigset, &sigoset); + (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); (void)umask(mask = umask(0)); mask = ~mask; - (void)sigprocmask(SIG_SETMASK, &sigoset, NULL); + (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); setlen = SET_LEN + 2; @@ -204,17 +210,14 @@ setmode(p) * or illegal bits. */ if (isdigit((unsigned char)*p)) { - perm = (mode_t)strtol(p, NULL, 8); - if (perm & ~(STANDARD_BITS|S_ISTXT)) { + perml = strtol(p, &ep, 8); + if (*ep || perml < 0 || perml & ~(STANDARD_BITS|S_ISTXT)) { free(saveset); return (NULL); } - while (*++p) - if (*p < '0' || *p > '7') { - free(saveset); - return (NULL); - } + perm = (mode_t)perml; ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); + set->cmd = 0; return (saveset); } @@ -339,8 +342,8 @@ apply: if (!*p) static BITCMD * addcmd(set, op, who, oparg, mask) BITCMD *set; - register int oparg, who; - register int op; + int oparg, who; + int op; u_int mask; { switch (op) { @@ -366,7 +369,7 @@ addcmd(set, op, who, oparg, mask) set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | ((who & S_IRGRP) ? CMD2_GBITS : 0) | ((who & S_IROTH) ? CMD2_OBITS : 0); - set->bits = ~0; + set->bits = (mode_t)~0; } else { set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; set->bits = mask; @@ -386,7 +389,7 @@ addcmd(set, op, who, oparg, mask) #ifdef SETMODE_DEBUG static void dumpmode(set) - register BITCMD *set; + BITCMD *set; { for (; set->cmd; ++set) (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", @@ -407,10 +410,10 @@ dumpmode(set) */ static void compress_mode(set) - register BITCMD *set; + BITCMD *set; { - register BITCMD *nset; - register int setbits, clrbits, Xbits, op; + BITCMD *nset; + int setbits, clrbits, Xbits, op; for (nset = set;;) { /* Copy over any 'u', 'g' and 'o' commands. */ diff --git a/gen/FreeBSD/setprogname.c b/gen/FreeBSD/setprogname.c new file mode 100644 index 0000000..654bef4 --- /dev/null +++ b/gen/FreeBSD/setprogname.c @@ -0,0 +1,19 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/setprogname.c,v 1.8 2002/03/29 22:43:41 markm Exp $"); + +#include +#include + +#include "libc_private.h" + +void +setprogname(const char *progname) +{ + const char *p; + + p = strrchr(progname, '/'); + if (p != NULL) + __progname = p + 1; + else + __progname = progname; +} diff --git a/gen/FreeBSD/setprogname.c.patch b/gen/FreeBSD/setprogname.c.patch new file mode 100644 index 0000000..6ca8162 --- /dev/null +++ b/gen/FreeBSD/setprogname.c.patch @@ -0,0 +1,21 @@ +--- setprogname.c.orig Mon Apr 28 15:05:02 2003 ++++ setprogname.c Fri May 16 14:13:59 2003 +@@ -3,6 +3,8 @@ + + #include + #include ++#include ++#define __progname (*_NSGetProgname()) + + #include "libc_private.h" + +@@ -13,7 +15,7 @@ + + p = strrchr(progname, '/'); + if (p != NULL) +- __progname = p + 1; ++ __progname = (char *)(p + 1); + else +- __progname = progname; ++ __progname = (char *)progname; + } diff --git a/gen/siginterrupt.3 b/gen/FreeBSD/siginterrupt.3 similarity index 97% rename from gen/siginterrupt.3 rename to gen/FreeBSD/siginterrupt.3 index d587425..34e1a9c 100644 --- a/gen/siginterrupt.3 +++ b/gen/FreeBSD/siginterrupt.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)siginterrupt.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/siginterrupt.3,v 1.13 2001/10/01 16:08:51 ru Exp $ +.\" $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 @@ -106,7 +106,9 @@ The 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 diff --git a/gen/siginterrupt.c b/gen/FreeBSD/siginterrupt.c similarity index 65% rename from gen/siginterrupt.c rename to gen/FreeBSD/siginterrupt.c index 2859c12..8c719f8 100644 --- a/gen/siginterrupt.c +++ b/gen/FreeBSD/siginterrupt.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,13 +31,22 @@ * 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; { @@ -69,7 +54,7 @@ siginterrupt(sig, flag) struct sigaction sa; int ret; - if ((ret = sigaction(sig, (struct sigaction *)0, &sa)) < 0) + if ((ret = _sigaction(sig, (struct sigaction *)0, &sa)) < 0) return (ret); if (flag) { sigaddset(&_sigintr, sig); @@ -78,5 +63,5 @@ siginterrupt(sig, flag) sigdelset(&_sigintr, sig); sa.sa_flags |= SA_RESTART; } - return (sigaction(sig, &sa, (struct sigaction *)0)); + return (_sigaction(sig, &sa, (struct sigaction *)0)); } diff --git a/gen/siglist.c b/gen/FreeBSD/siglist.c similarity index 78% rename from gen/siglist.c rename to gen/FreeBSD/siglist.c index c05d8a5..f269026 100644 --- a/gen/siglist.c +++ b/gen/FreeBSD/siglist.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -91,7 +72,7 @@ const char *const sys_signame[NSIG] = { "winch", /* SIGWINCH */ "info", /* SIGINFO */ "usr1", /* SIGUSR1 */ - "usr2", /* SIGUSR2 */ + "usr2" /* SIGUSR2 */ }; const char *const sys_siglist[NSIG] = { @@ -128,3 +109,4 @@ const char *const sys_siglist[NSIG] = { "User defined signal 1", /* SIGUSR1 */ "User defined signal 2" /* SIGUSR2 */ }; +const int sys_nsig = sizeof(sys_siglist) / sizeof(sys_siglist[0]); diff --git a/gen/FreeBSD/siglist.c.patch b/gen/FreeBSD/siglist.c.patch new file mode 100644 index 0000000..c2e14f7 --- /dev/null +++ b/gen/FreeBSD/siglist.c.patch @@ -0,0 +1,7 @@ +--- siglist.c.orig Sat Sep 7 01:14:19 2002 ++++ siglist.c Thu May 8 00:46:49 2003 +@@ -109,4 +109,3 @@ + "User defined signal 1", /* SIGUSR1 */ + "User defined signal 2" /* SIGUSR2 */ + }; +-const int sys_nsig = sizeof(sys_siglist) / sizeof(sys_siglist[0]); diff --git a/gen/signal.3 b/gen/FreeBSD/signal.3 similarity index 96% rename from gen/signal.3 rename to gen/FreeBSD/signal.3 index 6073b7b..9984726 100644 --- a/gen/signal.3 +++ b/gen/FreeBSD/signal.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)signal.3 8.3 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/signal.3,v 1.28 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/signal.3,v 1.32 2002/12/19 09:40:21 ru Exp $ .\" .Dd April 19, 1994 .Dt SIGNAL 3 @@ -50,7 +50,7 @@ or in .Fx Ns 's equivalent but easier to read typedef'd version: -.Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" +.Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; .Ft sig_t .Fn signal "int sig" "sig_t func" .Sh DESCRIPTION @@ -135,7 +135,7 @@ is possible on a descriptor (see .Pp The .Fa sig -parameter specifies which signal was received. +argument specifies which signal was received. The .Fa func procedure allows a user to choose the action upon receipt of a signal. @@ -190,7 +190,7 @@ 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). -This semantics could be changed with +These semantics could be changed with .Xr siginterrupt 3 . .Pp When a process which has installed signal handlers forks, @@ -204,19 +204,23 @@ ignored signals remain ignored. See .Xr sigaction 2 for a list of functions -that are considered safe for use in signal handler. +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 -.Fn Signal +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 -.Em Sig +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 diff --git a/gen/FreeBSD/signal.c b/gen/FreeBSD/signal.c new file mode 100644 index 0000000..a958347 --- /dev/null +++ b/gen/FreeBSD/signal.c @@ -0,0 +1,65 @@ +/* + * 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 */ + +sig_t +signal(s, a) + int s; + sig_t a; +{ + 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 (_sigaction(s, &sa, &osa) < 0) + return (SIG_ERR); + return (osa.sa_handler); +} diff --git a/gen/FreeBSD/signal.c.patch b/gen/FreeBSD/signal.c.patch new file mode 100644 index 0000000..c4169f4 --- /dev/null +++ b/gen/FreeBSD/signal.c.patch @@ -0,0 +1,53 @@ +--- signal.c.orig Thu Jan 31 16:57:29 2002 ++++ signal.c Fri May 16 14:16:12 2003 +@@ -47,10 +47,13 @@ + + sigset_t _sigintr; /* shared with siginterrupt */ + +-sig_t +-signal(s, a) ++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; + +@@ -59,7 +62,34 @@ + 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/sleep.3 b/gen/FreeBSD/sleep.3 similarity index 100% rename from gen/sleep.3 rename to gen/FreeBSD/sleep.3 diff --git a/gen/FreeBSD/sleep.c b/gen/FreeBSD/sleep.c new file mode 100644 index 0000000..bd48358 --- /dev/null +++ b/gen/FreeBSD/sleep.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[] = "@(#)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/srand48.c b/gen/FreeBSD/srand48.c similarity index 100% rename from gen/srand48.c rename to gen/FreeBSD/srand48.c diff --git a/gen/stringlist.3 b/gen/FreeBSD/stringlist.3 similarity index 83% rename from gen/stringlist.3 rename to gen/FreeBSD/stringlist.3 index 559d5da..f28dd5a 100644 --- a/gen/stringlist.3 +++ b/gen/FreeBSD/stringlist.3 @@ -1,6 +1,6 @@ -.\" $NetBSD: stringlist.3,v 1.2 1997/04/09 08:59:25 kleink Exp $ +.\" $NetBSD: stringlist.3,v 1.5 1999/03/22 19:44:46 garbled Exp $ .\" -.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" Copyright (c) 1997, 1999 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This file was contributed to The NetBSD Foundation by Luke Mewburn. @@ -33,9 +33,9 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/stringlist.3,v 1.7 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/stringlist.3,v 1.10 2003/02/23 01:47:47 ru Exp $ .\" -.Dd February 24, 1997 +.Dd November 28, 1999 .Os .Dt STRINGLIST 3 .Sh NAME @@ -51,7 +51,7 @@ .In stringlist.h .Ft StringList * .Fn sl_init -.Ft void +.Ft int .Fn sl_add "StringList *sl" "char *item" .Ft void .Fn sl_free "StringList *sl" "int freeall" @@ -64,7 +64,7 @@ functions manipulate stringlists, which are lists of strings that extend automatically if necessary. .Pp The -.Ar StringList +.Vt StringList structure has the following definition: .Bd -literal -offset indent typedef struct _stringlist { @@ -75,14 +75,14 @@ typedef struct _stringlist { .Ed .Pp .Bl -tag -width "sl_str" -offset indent -.It Ar sl_str +.It Va sl_str a pointer to the base of the array containing the list. -.It Ar sl_max +.It Va sl_max the size of -.Ar sl_str . -.It Ar sl_cur +.Va sl_str . +.It Va sl_cur the offset in -.Ar sl_str +.Va sl_str of the current element. .El .Pp @@ -91,34 +91,45 @@ The following stringlist manipulation functions are available: .It Fn sl_init Create a stringlist. Returns a pointer to a -.Ar StringList . +.Vt StringList , +or +.Dv NULL +in case of failure. .It Fn sl_free Releases memory occupied by -.Ar sl +.Fa sl and the -.Ar sl->sl_str +.Fa sl->sl_str array. If -.Ar freeall +.Fa freeall is non-zero, then each of the items within -.Ar sl->sl_str +.Fa sl->sl_str is released as well. .It Fn sl_add Add -.Ar item +.Fa item to -.Ar sl->sl_str +.Fa sl->sl_str at -.Ar sl->sl_cur , +.Fa sl->sl_cur , extending the size of -.Ar sl->sl_str +.Fa sl->sl_str . +Returns zero upon success, \-1 upon failure. .It Fn sl_find Find -.Ar item +.Fa item in -.Ar sl , +.Fa sl , returning NULL if it's not found. .El .Sh SEE ALSO .Xr free 3 , .Xr malloc 3 +.Sh HISTORY +The +.Nm +functions appeared in +.Fx 2.2.6 +and +.Nx 1.3 . diff --git a/gen/FreeBSD/stringlist.c b/gen/FreeBSD/stringlist.c new file mode 100644 index 0000000..1d977e4 --- /dev/null +++ b/gen/FreeBSD/stringlist.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/sysctl.3 b/gen/FreeBSD/sysctl.3 similarity index 97% rename from gen/sysctl.3 rename to gen/FreeBSD/sysctl.3 index 9fa2a4a..86675c7 100644 --- a/gen/sysctl.3 +++ b/gen/FreeBSD/sysctl.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95 -.\" $FreeBSD: src/lib/libc/gen/sysctl.3,v 1.51 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/sysctl.3,v 1.57 2002/12/19 09:40:21 ru Exp $ .\" .Dd January 23, 2001 .Dt SYSCTL 3 @@ -109,7 +109,9 @@ should be set to NULL. .Pp The size of the available data can be determined by calling .Fn sysctl -with a NULL parameter for +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 . @@ -153,7 +155,7 @@ function runs in about a third the time as the same request made via the .Fn sysctlbyname function). The -.Fn sysctlbyname +.Fn sysctlnametomib function is also useful for fetching mib prefixes and then adding a final component. For example, to fetch process information @@ -188,7 +190,7 @@ listed here, and described in separate sections below. .Bl -column CTLXMACHDEPXXX "Next level namesXXXXXX" -offset indent .It Sy "Name Next level names Description" .It "CTL\_DEBUG sys/sysctl.h Debugging" -.It "CTL\_VFS sys/mount.h Filesystem" +.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" @@ -233,39 +235,40 @@ Each time it runs, gets the list of debugging variables from the kernel and displays their current values. The system defines twenty -.Ns ( Va struct ctldebug ) +.Pq Vt "struct ctldebug" variables named -.Nm debug0 +.Va debug0 through -.Nm debug19 . +.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 -.Nm dospecialcheck +.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 filesystems. +is used to get general information about all file systems. One of its third level identifiers is VFS_MAXTYPENUM -that gives the highest valid filesystem type number. +that gives the highest valid file system type number. Its other third level identifier is VFS_CONF that -returns configuration information about the filesystem +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 -filesystem type number returned by a +file system type number returned by a .Xr statfs 2 call or from VFS_CONF. -The third level identifiers available for each filesystem +The third level identifiers available for each file system are given in the header file that defines the mount -argument structure for that filesystem. +argument structure for that file system. .Ss CTL_HW The string and integer information available for the CTL_HW level is detailed below. @@ -449,7 +452,7 @@ 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 EOPNOTSUPP . +.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 @@ -540,7 +543,7 @@ The fifth and sixth level names are as follows: .It Sy "Fifth level name Sixth level is:" .It "NET\_RT\_FLAGS rtflags" .It "NET\_RT\_DUMP None" -.It "NET\_RT\_IFLIST None" +.It "NET\_RT\_IFLIST 0 or if_index" .El .It Li PF_INET Get or set various global information about the IPv4 @@ -787,7 +790,7 @@ array specifies an intermediate rather than terminal name. The .Fa name array specifies a terminal name, but the actual name is not terminal. -.It Bq Er EOPNOTSUPP +.It Bq Er ENOENT The .Fa name array specifies a value that is unknown. diff --git a/gen/sysctl.c b/gen/FreeBSD/sysctl.c similarity index 78% rename from gen/sysctl.c rename to gen/FreeBSD/sysctl.c index c7a0b30..b6c89a0 100644 --- a/gen/sysctl.c +++ b/gen/FreeBSD/sysctl.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* +/*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -55,6 +31,11 @@ * 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 @@ -64,6 +45,10 @@ #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) @@ -86,16 +71,20 @@ sysctl(name, namelen, oldp, oldlenp, newp, newlen) switch (name[1]) { case USER_CS_PATH: - if (oldp && *oldlenp < sizeof(_PATH_STDPATH)) - return (ENOMEM); + 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)) - return (ENOMEM); + if (oldp && *oldlenp < sizeof(int)) { + errno = ENOMEM; + return (-1); + } *oldlenp = sizeof(int); if (oldp == NULL) return (0); diff --git a/gen/sysctlbyname.c b/gen/FreeBSD/sysctlbyname.c similarity index 89% rename from gen/sysctlbyname.c rename to gen/FreeBSD/sysctlbyname.c index 27e3ca9..e949a5c 100644 --- a/gen/sysctlbyname.c +++ b/gen/FreeBSD/sysctlbyname.c @@ -6,9 +6,11 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $FreeBSD: src/lib/libc/gen/sysctlbyname.c,v 1.4 1999/08/27 23:59:01 peter Exp $ - * */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/sysctlbyname.c,v 1.5 2002/02/01 00:57:29 obrien Exp $"); + #include #include #include diff --git a/gen/FreeBSD/sysctlnametomib.c b/gen/FreeBSD/sysctlnametomib.c new file mode 100644 index 0000000..1a932ec --- /dev/null +++ b/gen/FreeBSD/sysctlnametomib.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/telldir.c b/gen/FreeBSD/telldir.c similarity index 56% rename from gen/telldir.c rename to gen/FreeBSD/telldir.c index a084d8a..f321910 100644 --- a/gen/telldir.c +++ b/gen/FreeBSD/telldir.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,11 +31,23 @@ * 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 @@ -68,44 +56,26 @@ */ #define SINGLEUSE -/* - * 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 { - struct ddloc *loc_next;/* next structure in list */ - long loc_index; /* key associated with structure */ - long loc_seek; /* magic cookie returned by getdirentries */ - long loc_loc; /* offset of entry in buffer */ -}; - -#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */ -#define LOCHASH(i) ((i)&(NDIRHASH-1)) - -static long dd_loccnt; /* Index of entry for sequential readdir's */ -static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */ - /* * return a pointer into a directory */ long telldir(dirp) - const DIR *dirp; + DIR *dirp; { - register int index; - register struct ddloc *lp; + struct ddloc *lp; if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) return (-1); - index = dd_loccnt++; - lp->loc_index = index; + if (__isthreaded) + _pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock); + lp->loc_index = dirp->dd_td->td_loccnt++; lp->loc_seek = dirp->dd_seek; lp->loc_loc = dirp->dd_loc; - lp->loc_next = dd_hash[LOCHASH(index)]; - dd_hash[LOCHASH(index)] = lp; - return (index); + LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); + if (__isthreaded) + _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock); + return (lp->loc_index); } /* @@ -114,20 +84,15 @@ telldir(dirp) */ void _seekdir(dirp, loc) - register DIR *dirp; + DIR *dirp; long loc; { - register struct ddloc *lp; - register struct ddloc **prevlp; + struct ddloc *lp; struct dirent *dp; - prevlp = &dd_hash[LOCHASH(loc)]; - lp = *prevlp; - while (lp != NULL) { + LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { if (lp->loc_index == loc) break; - prevlp = &lp->loc_next; - lp = lp->loc_next; } if (lp == NULL) return; @@ -137,13 +102,32 @@ _seekdir(dirp, loc) dirp->dd_seek = lp->loc_seek; dirp->dd_loc = 0; while (dirp->dd_loc < lp->loc_loc) { - dp = readdir(dirp); + dp = _readdir_unlocked(dirp); if (dp == NULL) break; } found: #ifdef SINGLEUSE - *prevlp = lp->loc_next; + LIST_REMOVE(lp, loc_lqe); free((caddr_t)lp); #endif } + +/* + * 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); +} diff --git a/compat-43/setrgid.c b/gen/FreeBSD/telldir.h similarity index 51% rename from compat-43/setrgid.c rename to gen/FreeBSD/telldir.h index 3fa5a92..82cf9c1 100644 --- a/compat-43/setrgid.c +++ b/gen/FreeBSD/telldir.h @@ -1,31 +1,10 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * + * 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: @@ -34,11 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@ -53,19 +28,39 @@ * LIABILITY, OR TORT (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 +#include -int -#ifdef __STDC__ -setrgid(gid_t rgid) -#else -setrgid(rgid) - int rgid; -#endif -{ +/* + * 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 */ + long loc_seek; /* magic cookie returned by getdirentries */ + 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 */ +}; + +struct dirent *_readdir_unlocked(DIR *); +void _reclaim_telldir(DIR *); +void _seekdir(DIR *, long); - return (setregid(rgid, -1)); -} +#endif diff --git a/gen/termios.c b/gen/FreeBSD/termios.c similarity index 67% rename from gen/termios.c rename to gen/FreeBSD/termios.c index 55ec2ef..65f8141 100644 --- a/gen/termios.c +++ b/gen/FreeBSD/termios.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,19 +31,22 @@ * 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 $"); +#include "namespace.h" #include +#include #include -#include #include -#define KERNEL /* XXX - FREAD and FWRITE ifdef'd KERNEL*/ -#include -#undef KERNEL #include -#include #include #include +#include "un-namespace.h" int tcgetattr(fd, t) @@ -75,7 +54,7 @@ tcgetattr(fd, t) struct termios *t; { - return (ioctl(fd, TIOCGETA, t)); + return (_ioctl(fd, TIOCGETA, t)); } int @@ -92,11 +71,11 @@ tcsetattr(fd, opt, t) } switch (opt & ~TCSASOFT) { case TCSANOW: - return (ioctl(fd, TIOCSETA, t)); + return (_ioctl(fd, TIOCSETA, t)); case TCSADRAIN: - return (ioctl(fd, TIOCSETAW, t)); + return (_ioctl(fd, TIOCSETAW, t)); case TCSAFLUSH: - return (ioctl(fd, TIOCSETAF, t)); + return (_ioctl(fd, TIOCSETAF, t)); default: errno = EINVAL; return (-1); @@ -104,26 +83,21 @@ tcsetattr(fd, opt, t) } int -#if __STDC__ tcsetpgrp(int fd, pid_t pgrp) -#else -tcsetpgrp(fd, pgrp) - int fd; - pid_t pgrp; -#endif { int s; s = pgrp; - return (ioctl(fd, TIOCSPGRP, &s)); + return (_ioctl(fd, TIOCSPGRP, &s)); } pid_t tcgetpgrp(fd) + int fd; { int s; - if (ioctl(fd, TIOCGPGRP, &s) < 0) + if (_ioctl(fd, TIOCGPGRP, &s) < 0) return ((pid_t)-1); return ((pid_t)s); @@ -184,14 +158,17 @@ cfmakeraw(t) struct termios *t; { - t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + 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|ECHONL|ICANON|ISIG|IEXTEN); + t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN); t->c_cflag &= ~(CSIZE|PARENB); - t->c_cflag |= CS8; - /* XXX set MIN/TIME */ + t->c_cflag |= CS8|CREAD; + t->c_cc[VMIN] = 1; + t->c_cc[VTIME] = 0; } +int tcsendbreak(fd, len) int fd, len; { @@ -199,21 +176,25 @@ tcsendbreak(fd, len) sleepytime.tv_sec = 0; sleepytime.tv_usec = 400000; - if (ioctl(fd, TIOCSBRK, 0) == -1) + if (_ioctl(fd, TIOCSBRK, 0) == -1) return (-1); - (void)select(0, 0, 0, 0, &sleepytime); - if (ioctl(fd, TIOCCBRK, 0) == -1) + (void)_select(0, 0, 0, 0, &sleepytime); + if (_ioctl(fd, TIOCCBRK, 0) == -1) return (-1); return (0); } -tcdrain(fd) +int +__tcdrain(fd) int fd; { - - return (ioctl(fd, TIOCDRAIN, 0)); + return (_ioctl(fd, TIOCDRAIN, 0)); } +__weak_reference(__tcdrain, tcdrain); +__weak_reference(__tcdrain, _tcdrain); + +int tcflush(fd, which) int fd, which; { @@ -233,9 +214,10 @@ tcflush(fd, which) errno = EINVAL; return (-1); } - return (ioctl(fd, TIOCFLUSH, &com)); + return (_ioctl(fd, TIOCFLUSH, &com)); } +int tcflow(fd, action) int fd, action; { @@ -244,15 +226,15 @@ tcflow(fd, action) switch (action) { case TCOOFF: - return (ioctl(fd, TIOCSTOP, 0)); + return (_ioctl(fd, TIOCSTOP, 0)); case TCOON: - return (ioctl(fd, TIOCSTART, 0)); + return (_ioctl(fd, TIOCSTART, 0)); case TCION: 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) + if (c != _POSIX_VDISABLE && _write(fd, &c, sizeof(c)) == -1) return (-1); return (0); default: diff --git a/gen/time.3 b/gen/FreeBSD/time.3 similarity index 100% rename from gen/time.3 rename to gen/FreeBSD/time.3 diff --git a/gen/FreeBSD/time.3.patch b/gen/FreeBSD/time.3.patch new file mode 100644 index 0000000..e01ce28 --- /dev/null +++ b/gen/FreeBSD/time.3.patch @@ -0,0 +1,17 @@ +Index: time.3 +=================================================================== +RCS file: /cvs/root/Libc/gen/FreeBSD/time.3,v +retrieving revision 1.2 +diff -u -r1.2 time.3 +--- time.3 2003/05/20 22:21:03 1.2 ++++ time.3 2003/07/08 23:12:00 +@@ -53,7 +53,8 @@ + .Fn time + function + returns the value of time in seconds since 0 hours, 0 minutes, +-0 seconds, January 1, 1970, Coordinated Universal Time. ++0 seconds, January 1, 1970, Coordinated Universal Time, ++without including leap seconds. + .Pp + A copy of the time value may be saved to the area indicated by the + pointer diff --git a/gen/time.c b/gen/FreeBSD/time.c similarity index 65% rename from gen/time.c rename to gen/FreeBSD/time.c index 9730369..4b1d27a 100644 --- a/gen/time.c +++ b/gen/FreeBSD/time.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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.2 2002/03/22 21:52:05 obrien Exp $"); #include #include diff --git a/gen/times.3 b/gen/FreeBSD/times.3 similarity index 100% rename from gen/times.3 rename to gen/FreeBSD/times.3 diff --git a/gen/times.c b/gen/FreeBSD/times.c similarity index 70% rename from gen/times.c rename to gen/FreeBSD/times.c index e5748d0..5bdc607 100644 --- a/gen/times.c +++ b/gen/FreeBSD/times.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 @@ -69,7 +50,7 @@ clock_t times(tp) - register struct tms *tp; + struct tms *tp; { struct rusage ru; struct timeval t; diff --git a/gen/timezone.3 b/gen/FreeBSD/timezone.3 similarity index 95% rename from gen/timezone.3 rename to gen/FreeBSD/timezone.3 index bf1637f..27caaa2 100644 --- a/gen/timezone.3 +++ b/gen/FreeBSD/timezone.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)timezone.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/timezone.3,v 1.7 2000/11/10 17:44:58 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/timezone.3,v 1.9 2002/12/19 09:40:21 ru Exp $ .\" .Dd April 19, 1994 .Dt TIMEZONE 3 @@ -54,13 +54,15 @@ See The .Fn timezone function returns a pointer to a time zone abbreviation for the specified -.Ar zone +.Fa zone and -.Ar dst +.Fa dst values. -.Ar Zone +The +.Fa zone +argument is the number of minutes west of GMT and -.Ar dst +.Fa dst is non-zero if daylight savings time is in effect. .Sh SEE ALSO .Xr ctime 3 diff --git a/gen/timezone.c b/gen/FreeBSD/timezone.c similarity index 64% rename from gen/timezone.c rename to gen/FreeBSD/timezone.c index 2cbacfe..8d8139a 100644 --- a/gen/timezone.c +++ b/gen/FreeBSD/timezone.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,13 +31,18 @@ * 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 -#include +#define TZ_MAX_CHARS 255 char *_tztab(); @@ -80,11 +61,11 @@ timezone(zone, dst) int zone, dst; { - register char *beg, + char *beg, *end; - if (beg = getenv("TZNAME")) { /* set in environment */ - if (end = index(beg, ',')) { /* "PST,PDT" */ + if ( (beg = getenv("TZNAME")) ) { /* set in environment */ + if ( (end = index(beg, ',')) ) {/* "PST,PDT" */ if (dst) return(++end); *end = '\0'; @@ -103,22 +84,22 @@ static struct zone { 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 */ + {-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 */ + {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 + {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} }; /* @@ -130,11 +111,11 @@ static struct zone { */ char * _tztab(zone,dst) - register int zone; + int zone; int dst; { - register struct zone *zp; - register char sign; + struct zone *zp; + char sign; for (zp = zonetab; zp->offset != -1;++zp) /* static tables */ if (zp->offset == zone) { @@ -150,6 +131,7 @@ _tztab(zone,dst) } else sign = '-'; - (void)sprintf(czone,"GMT%c%d:%02d",sign,zone / 60,zone % 60); + (void)snprintf(czone, sizeof(czone), + "GMT%c%d:%02d",sign,zone / 60,zone % 60); return(czone); } diff --git a/gen/ttyname.3 b/gen/FreeBSD/ttyname.3 similarity index 97% rename from gen/ttyname.3 rename to gen/FreeBSD/ttyname.3 index 8a4b649..c1d1b4f 100644 --- a/gen/ttyname.3 +++ b/gen/FreeBSD/ttyname.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/ttyname.3,v 1.9 2001/10/01 16:08:51 ru Exp $ +.\" $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 @@ -59,7 +59,7 @@ These descriptors are not related to the standard typedef, but refer to the special device files found in .Pa /dev and named -.Pa /dev/tty Ns Em xx +.Pa /dev/tty Ns Ar xx and for which an entry exists in the initialization file .Pa /etc/ttys . diff --git a/gen/ttyname.c b/gen/FreeBSD/ttyname.c similarity index 50% rename from gen/ttyname.c rename to gen/FreeBSD/ttyname.c index fdf9276..b8412d7 100644 --- a/gen/ttyname.c +++ b/gen/FreeBSD/ttyname.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,51 +31,141 @@ * 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.12 2002/02/01 01:32:19 obrien Exp $"); +#include "namespace.h" #include #include -#include -#include - #include #include -#include +#include +#include +#include #include #include -#include +#include +#include "un-namespace.h" + +#include +#include "libc_private.h" + +static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV; +static char *oldttyname(int, struct stat *); +static char *ttyname_threaded(int fd); +static char *ttyname_unthreaded(int fd); -static char *buf = NULL; -static char *oldttyname __P((int, struct stat *)); +static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_key_t ttyname_key; +static int ttyname_init = 0; char * -ttyname(fd) - int fd; +ttyname(int fd) +{ + char *ret; + + if (__isthreaded == 0) + ret = ttyname_unthreaded(fd); + else + ret = ttyname_threaded(fd); + return (ret); +} + +char * +ttyname_r(int fd, char *buf, size_t len) +{ + struct dirent *dirp; + DIR *dp; + struct stat dsb; + struct stat sb; + char *rval; + int minlen; + + rval = NULL; + + /* Must be a terminal. */ + if (!isatty(fd)) + return (rval); + /* Must be a character device. */ + if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) + return (rval); + /* Must have enough room */ + if (len <= sizeof(_PATH_DEV)) + return (rval); + + if ((dp = opendir(_PATH_DEV)) != NULL) { + memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV)); + for (rval = NULL; (dirp = readdir(dp)) != NULL;) { + if (dirp->d_fileno != sb.st_ino) + continue; + minlen = (len - (sizeof(_PATH_DEV) - 1)) < (dirp->d_namlen + 1) ? + (len - (sizeof(_PATH_DEV) - 1)) : (dirp->d_namlen + 1); + memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, minlen); + if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev || + sb.st_ino != dsb.st_ino) + continue; + rval = buf; + break; + } + (void) closedir(dp); + } + return (rval); +} + +static char * +ttyname_threaded(int fd) +{ + char *buf; + + if (ttyname_init == 0) { + _pthread_mutex_lock(&ttyname_lock); + if (ttyname_init == 0) { + if (_pthread_key_create(&ttyname_key, free)) { + _pthread_mutex_unlock(&ttyname_lock); + 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) { + free(buf); + return (NULL); + } + } else { + return (NULL); + } + } + return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN)); +} + +static char * +ttyname_unthreaded(int fd) { - struct stat sb; - struct termios term; - DB *db; - DBT data, key; + struct stat sb; + struct termios ttyb; + DB *db; + DBT data, key; struct { mode_t type; dev_t dev; } bkey; - if( buf == NULL ) { - buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN); - if( buf == NULL ) - return NULL; - strcpy(buf, _PATH_DEV); - } - /* Must be a terminal. */ - if (ioctl(fd, TIOCGETA, &term) < 0) + 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) || !S_ISCHR(sb.st_mode)) return (NULL); - db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL); - if (db) { + if ( (db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) ) { memset(&bkey, 0, sizeof(bkey)); bkey.type = S_IFCHR; bkey.dev = sb.st_rdev; @@ -117,20 +183,12 @@ ttyname(fd) } static char * -oldttyname(fd, sb) - int fd; - struct stat *sb; +oldttyname(int fd, struct stat *sb) { - register struct dirent *dirp; - register DIR *dp; - struct stat dsb; - - if( buf == NULL ) { - buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN); - if( buf == NULL ) - return NULL; - strcpy(buf, _PATH_DEV); - } + struct dirent *dirp; + struct stat dsb; + DIR *dp; + if ((dp = opendir(_PATH_DEV)) == NULL) return (NULL); diff --git a/gen/ttyslot.c b/gen/FreeBSD/ttyslot.c similarity index 62% rename from gen/ttyslot.c rename to gen/FreeBSD/ttyslot.c index 508b2a0..0d7359c 100644 --- a/gen/ttyslot.c +++ b/gen/FreeBSD/ttyslot.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -64,20 +45,20 @@ int ttyslot() { - register struct ttyent *ttyp; - register int slot; - register char *p; + 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, '/')) + for (cnt = 0; cnt < 3; ++cnt) + if ( (name = ttyname(cnt)) ) { + if ( (p = rindex(name, '/')) ) ++p; else p = name; - for (slot = 1; ttyp = getttyent(); ++slot) + for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, p)) { endttyent(); return(slot); diff --git a/gen/ualarm.3 b/gen/FreeBSD/ualarm.3 similarity index 100% rename from gen/ualarm.3 rename to gen/FreeBSD/ualarm.3 diff --git a/gen/ualarm.c b/gen/FreeBSD/ualarm.c similarity index 69% rename from gen/ualarm.c rename to gen/FreeBSD/ualarm.c index ca9a368..33aded0 100644 --- a/gen/ualarm.c +++ b/gen/FreeBSD/ualarm.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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.3 2002/02/01 01:08:48 obrien Exp $"); #include #include @@ -68,14 +49,14 @@ */ unsigned ualarm(usecs, reload) - register unsigned usecs; - register unsigned reload; + unsigned usecs; + unsigned 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; diff --git a/gen/FreeBSD/ulimit.3 b/gen/FreeBSD/ulimit.3 new file mode 100644 index 0000000..3dc745f --- /dev/null +++ b/gen/FreeBSD/ulimit.3 @@ -0,0 +1,98 @@ +.\" 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 +.Fn ulimit "int cmd" "..." +.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 in units of 512 blocks of +the current process. +.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. +.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/FreeBSD/ulimit.c b/gen/FreeBSD/ulimit.c new file mode 100644 index 0000000..d25ff47 --- /dev/null +++ b/gen/FreeBSD/ulimit.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/unvis.3 b/gen/FreeBSD/unvis.3 similarity index 96% rename from gen/unvis.3 rename to gen/FreeBSD/unvis.3 index 35e36b6..24492cc 100644 --- a/gen/unvis.3 +++ b/gen/FreeBSD/unvis.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)unvis.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/gen/unvis.3,v 1.14 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/unvis.3,v 1.15 2002/12/18 13:33:02 ru Exp $ .\" .Dd December 11, 1993 .Dt UNVIS 3 @@ -61,33 +61,33 @@ by the .Xr vis 3 function, back into the original form. Unvis is called with successive characters in -.Ar c +.Fa c until a valid sequence is recognized, at which time the decoded character is available at the character pointed to by -.Ar cp . +.Fa cp . Strunvis decodes the characters pointed to by -.Ar src +.Fa src into the buffer pointed to by -.Ar dst . +.Fa dst . .Pp The .Fn strunvis function simply copies -.Ar src +.Fa src to -.Ar dst , +.Fa dst , decoding any escape sequences along the way, and returns the number of characters placed into -.Ar dst , +.Fa dst , or \-1 if an invalid escape sequence was detected. The size of -.Ar dst +.Fa dst should be equal to the size of -.Ar src +.Fa src (that is, no expansion takes place during decoding). .Pp @@ -97,7 +97,7 @@ function does the same as the .Fn strunvis function, but it allows you to add a flag that specifies the style the string -.Ar src +.Fa src is encoded with. Currently, the only supported flag is .Dv VIS_HTTPSTYLE . @@ -141,13 +141,13 @@ unknown state. The decoder is placed into the starting state. When all bytes in the stream have been processed, call .Fn unvis one more time with -.Ar flag +.Fa flag set to .Dv UNVIS_END to extract any remaining character (the character passed in is ignored). .Pp The -.Ar flag +.Fa flag argument is also used to specify the encoding style of the source. If set to .Dv VIS_HTTPSTYLE , diff --git a/gen/unvis.c b/gen/FreeBSD/unvis.c similarity index 75% rename from gen/unvis.c rename to gen/FreeBSD/unvis.c index b134fb8..491df36 100644 --- a/gen/unvis.c +++ b/gen/FreeBSD/unvis.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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.8 2003/02/16 17:29:09 nectar Exp $"); #include #include @@ -70,8 +51,12 @@ #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 @@ -86,22 +71,33 @@ unvis(cp, c, astate, flag) if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { *astate = S_GROUND; return (UNVIS_VALID); - } + } return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } - switch (*astate) { + 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(c))) { + *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a'); + *astate = S_HEX2; + return (0); + } + } switch(c) { case '\\': *cp = c; @@ -170,7 +166,7 @@ unvis(cp, c, astate, flag) } *astate = S_GROUND; return (UNVIS_SYNBAD); - + case S_META: if (c == '-') *astate = S_META1; @@ -181,12 +177,12 @@ unvis(cp, c, astate, flag) return (UNVIS_SYNBAD); } return (0); - + case S_META1: *astate = S_GROUND; *cp |= c; return (UNVIS_VALID); - + case S_CTRL: if (c == '?') *cp |= 0177; @@ -197,15 +193,15 @@ unvis(cp, c, astate, flag) case S_OCTAL2: /* second possible octal digit */ if (isoctal(c)) { - /* - * yes - and maybe a third + /* + * yes - and maybe a third */ *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; + *astate = S_OCTAL3; return (0); - } - /* - * no - done with current sequence, push back passed char + } + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); @@ -220,10 +216,17 @@ unvis(cp, c, astate, flag) * we were done, push back passed char */ return (UNVIS_VALIDPUSH); - - default: - /* - * decoder in unknown state - (probably uninitialized) + + case S_HEX2: /* second mandatory hex digit */ + if (ishex(tolower(c))) { + *cp = (isdigit(c) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower(c) - 'a' + 10)); + } + *astate = S_GROUND; + return (UNVIS_VALID); + + default: + /* + * decoder in unknown state - (probably uninitialized) */ *astate = S_GROUND; return (UNVIS_SYNBAD); @@ -231,7 +234,7 @@ unvis(cp, c, astate, flag) } /* - * strunvis - decode src into dst + * strunvis - decode src into dst * * Number of chars decoded into dst is returned, -1 on error. * Dst is null terminated. @@ -239,14 +242,14 @@ unvis(cp, c, astate, flag) int strunvis(dst, src) - register char *dst; - register const char *src; + char *dst; + const char *src; { - register char c; + char c; char *start = dst; int state = 0; - while (c = *src++) { + while ( (c = *src++) ) { again: switch (unvis(dst, c, &state, 0)) { case UNVIS_VALID: @@ -267,3 +270,34 @@ strunvis(dst, src) *dst = '\0'; return (dst - start); } + +int +strunvisx(dst, src, flag) + char *dst; + const char *src; +{ + 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/usleep.3 b/gen/FreeBSD/usleep.3 similarity index 97% rename from gen/usleep.3 rename to gen/FreeBSD/usleep.3 index 058c7d5..e0369ca 100644 --- a/gen/usleep.3 +++ b/gen/FreeBSD/usleep.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)usleep.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.10.2.7 2001/12/14 18:33:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.17 2001/10/01 16:08:51 ru Exp $ .\" .Dd February 13, 1998 .Dt USLEEP 3 diff --git a/gen/usleep.c b/gen/FreeBSD/usleep.c similarity index 91% rename from gen/usleep.c rename to gen/FreeBSD/usleep.c index 15004e1..9cc536a 100644 --- a/gen/usleep.c +++ b/gen/FreeBSD/usleep.c @@ -32,15 +32,15 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -#if 0 static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; -#endif -static char rcsid[] = - "$FreeBSD: src/lib/libc/gen/usleep.c,v 1.25 2000/01/27 23:06:22 jasone Exp $"; #endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/usleep.c,v 1.27 2002/02/01 00:57:29 obrien Exp $"); +#include "namespace.h" #include #include +#include "un-namespace.h" int usleep(useconds) @@ -50,5 +50,5 @@ usleep(useconds) time_to_sleep.tv_nsec = (useconds % 1000000) * 1000; time_to_sleep.tv_sec = useconds / 1000000; - return (nanosleep(&time_to_sleep, NULL)); + return (_nanosleep(&time_to_sleep, NULL)); } diff --git a/gen/utime.3 b/gen/FreeBSD/utime.3 similarity index 96% rename from gen/utime.3 rename to gen/FreeBSD/utime.3 index deb5336..7dc3611 100644 --- a/gen/utime.3 +++ b/gen/FreeBSD/utime.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)utime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/utime.3,v 1.10 2001/10/01 16:08:51 ru Exp $ +.\" $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 @@ -41,7 +41,6 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/types.h .In utime.h .Ft int .Fn utime "const char *file" "const struct utimbuf *timep" diff --git a/gen/utime.c b/gen/FreeBSD/utime.c similarity index 67% rename from gen/utime.c rename to gen/FreeBSD/utime.c index 65a68b3..cefa020 100644 --- a/gen/utime.c +++ b/gen/FreeBSD/utime.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 diff --git a/gen/vis.3 b/gen/FreeBSD/vis.3 similarity index 96% rename from gen/vis.3 rename to gen/FreeBSD/vis.3 index cd5f307..894b03b 100644 --- a/gen/vis.3 +++ b/gen/FreeBSD/vis.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)vis.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/vis.3,v 1.18 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/gen/vis.3,v 1.20 2002/12/19 09:40:21 ru Exp $ .\" .Dd July 25, 1996 .Dt VIS 3 @@ -67,7 +67,9 @@ thus, when encoding a set of characters into a buffer, the size of the buffer should be four times the number of characters encoded, plus one for the trailing .Dv NUL . -The flag parameter is used for altering the default range of +The +.Fa flag +argument is used for altering the default range of characters considered for encoding and for altering the visual representation. The additional character, @@ -227,7 +229,9 @@ The following sequences are used to represent the indicated characters: .Li \e0 Tn - NUL No (000) .Ed .Pp -When using this format, the nextc parameter is looked at to determine +When using this format, the +.Fa nextc +argument is looked at to determine if a .Dv NUL character can be encoded as @@ -243,13 +247,13 @@ Use URI encoding as described in RFC 1808. The form is .Ql %dd where -.Em d +.Ar d represents a hexadecimal digit. .It Dv VIS_OCTAL Use a three digit octal sequence. The form is .Ql \eddd where -.Em d +.Ar d represents an octal digit. .El .Pp diff --git a/gen/vis.c b/gen/FreeBSD/vis.c similarity index 74% rename from gen/vis.c rename to gen/FreeBSD/vis.c index 54d9e43..f9d6865 100644 --- a/gen/vis.c +++ b/gen/FreeBSD/vis.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,10 +31,16 @@ * 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.11 2002/08/19 17:14:58 jmallett Exp $"); #include #include #include +#include #include #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') @@ -68,11 +50,28 @@ */ char * vis(dst, c, flag, nextc) - register char *dst; + char *dst; int c, nextc; - register int flag; + int flag; { - if ((u_int)c <= UCHAR_MAX && isgraph(c) || + c = (unsigned char)c; + + if (flag & VIS_HTTPSTYLE) { + /* Described in RFC 1808 */ + if (!(isalnum(c) /* alpha-numeric */ + /* safe */ + || c == '$' || c == '-' || c == '_' || c == '.' || c == '+' + /* extra */ + || c == '!' || c == '*' || c == '\'' || c == '(' + || c == ')' || c == ',')) { + *dst++ = '%'; + snprintf(dst, 4, (c < 16 ? "0%X" : "%X"), c); + dst += 2; + goto done; + } + } + + if (isgraph(c) || ((flag & VIS_SP) == 0 && c == ' ') || ((flag & VIS_TAB) == 0 && c == '\t') || ((flag & VIS_NL) == 0 && c == '\n') || @@ -98,11 +97,7 @@ vis(dst, c, flag, nextc) *dst++ = '\\'; *dst++ = 'b'; goto done; -#if __STDC__ case '\a': -#else - case '\007': -#endif *dst++ = '\\'; *dst++ = 'a'; goto done; @@ -132,7 +127,7 @@ vis(dst, c, flag, nextc) goto done; } } - if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { *dst++ = '\\'; *dst++ = ((u_char)c >> 6 & 07) + '0'; *dst++ = ((u_char)c >> 3 & 07) + '0'; @@ -162,24 +157,24 @@ done: /* * 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 NULL, - * is returned. + * 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) - register char *dst; - register const char *src; + char *dst; + const char *src; int flag; { - register char c; + char c; char *start; - for (start = dst; c = *src;) + for (start = dst; (c = *src); ) dst = vis(dst, c, flag, *++src); *dst = '\0'; return (dst - start); @@ -187,9 +182,9 @@ strvis(dst, src, flag) int strvisx(dst, src, len, flag) - register char *dst; - register const char *src; - register size_t len; + char *dst; + const char *src; + size_t len; int flag; { int c; diff --git a/gen/wait.c b/gen/FreeBSD/wait.c similarity index 62% rename from gen/wait.c rename to gen/FreeBSD/wait.c index cf05bb9..8cb80a4 100644 --- a/gen/wait.c +++ b/gen/FreeBSD/wait.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,14 +31,24 @@ * 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" -pid_t wait(istat) - int *istat; +pid_t +__wait(int *istat) { - return (wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); + return (_wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); } +__weak_reference(__wait, wait); +__weak_reference(__wait, _wait); diff --git a/gen/wait3.c b/gen/FreeBSD/wait3.c similarity index 64% rename from gen/wait3.c rename to gen/FreeBSD/wait3.c index a2ccb1c..a4b91a7 100644 --- a/gen/wait3.c +++ b/gen/FreeBSD/wait3.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,10 +31,18 @@ * 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) @@ -66,5 +50,5 @@ wait3(istat, options, rup) int options; struct rusage *rup; { - return (wait4(WAIT_ANY, istat, options, rup)); + return (_wait4(WAIT_ANY, istat, options, rup)); } diff --git a/gen/FreeBSD/waitpid.c b/gen/FreeBSD/waitpid.c new file mode 100644 index 0000000..273d1f3 --- /dev/null +++ b/gen/FreeBSD/waitpid.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[] = "@(#)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" + +pid_t +__waitpid(pid_t pid, int *istat, int options) +{ + return (_wait4(pid, istat, options, (struct rusage *)0)); +} + +__weak_reference(__waitpid, waitpid); +__weak_reference(__waitpid, _waitpid); diff --git a/gen/Makefile.inc b/gen/Makefile.inc index ed08ce0..b8e0009 100644 --- a/gen/Makefile.inc +++ b/gen/Makefile.inc @@ -4,40 +4,29 @@ # machine-independent gen sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/gen ${.CURDIR}/gen -CFLAGS+= -I${.CURDIR}/pthreads +CFLAGS += -I${.CURDIR}/pthreads -SRCS += NSSystemDirectories.c getpagesize.c siginterrupt.c \ - alarm.c getpass.c siglist.c \ - assert.c getttyent.c signal.c \ - getusershell.c sigsetops.c \ - clock.c getvfsbyname.c sleep.c \ - closedir.c stack_logging.c \ - confstr.c strchr.c \ - crypt.c sysconf.c \ - ctermid.c isatty.c sysctl.c \ - isnan.c sysctlbyname.c \ - daemon.c malloc.c syslog.c \ - devname.c nanosleep.c telldir.c \ - difftime.c nice.c termios.c \ - disklabel.c nlist.c time.c \ - err.c opendir.c times.c \ - errlst.c pause.c timezone.c \ - exec.c popen.c ttyname.c \ - fnmatch.c psignal.c ttyslot.c \ - ualarm.c \ - ftok.c raise.c uname.c \ - fts.c unvis.c \ - getbsize.c readdir.c usleep.c \ - getcap.c rewinddir.c utime.c \ - getcwd.c scalable_malloc.c vis.c \ - scandir.c wait.c \ - gethostname.c seekdir.c wait3.c \ - getloadavg.c sethostname.c waitpid.c \ - getlogin.c setlogin.c zone.c \ - getmntinfo.c setmode.c \ - _rand48.c erand48.c lcong48.c mrand48.c seed48.c drand48.c jrand48.c \ - nrand48.c srand48.c lrand48.c basename.c dirname.c arc4random.c \ - strtofflags.c lockf.c readdir_r.c ulimit.c +SRCS += NSSystemDirectories.c OSSystemInfo.c arc4random.c assert.c cache.c \ + confstr.c crypt.c devname.c disklabel.c errlst.c fts.c \ + getloadavg.c getttyent.c getusershell.c getvfsbyname.c isnan.c \ + malloc.c nanosleep.c nlist.c scalable_malloc.c setlogin.c sigsetops.c \ + stack_logging.c strtofflags.c sysconf.c syslog.c uname.c zone.c + +.include "Makefile.fbsd_begin" +FBSDSRCS = _rand48.c alarm.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 fnmatch.c ftok.c getbsize.c getcap.c getcwd.c gethostname.c \ + getlogin.c getmntinfo.c getpagesize.c getprogname.c isatty.c \ + jrand48.c lcong48.c lockf.c lrand48.c mrand48.c nice.c nrand48.c \ + opendir.c pause.c popen.c pselect.c psignal.c raise.c readdir.c \ + readpassphrase.c rewinddir.c scandir.c seed48.c seekdir.c \ + sethostname.c setmode.c setprogname.c siginterrupt.c siglist.c \ + signal.c sleep.c srand48.c stringlist.c sysctl.c sysctlbyname.c \ + sysctlnametomib.c telldir.c termios.c time.c times.c timezone.c \ + ttyname.c ttyslot.c ualarm.c ulimit.c unvis.c usleep.c utime.c vis.c \ + wait.c wait3.c waitpid.c +FBSDORIGHDRS = rand48.h telldir.h +.include "Makefile.fbsd_end" # machine-dependent gen sources @@ -46,37 +35,34 @@ SRCS += NSSystemDirectories.c getpagesize.c siginterrupt.c \ .endif .if ${LIB} == "c" -MAN3+= alarm.3 arc4random.3 clock.3 \ - basename.3 \ - confstr.3 ctermid.3 daemon.3 \ - devname.3 directory.3 dirname.3 \ - err.3 exec.3 fmtcheck.3 fnmatch.3 frexp.3 ftok.3 fts.3 \ - getbootfile.3 getbsize.3 getcap.3 getcwd.3 \ - getdomainname.3 getfsent.3 \ - getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \ - getmntinfo.3 getnetgrent.3 getobjformat.3 \ - getpagesize.3 getpass.3 getpeereid.3 getpwent.3 \ - getttyent.3 getusershell.3 getvfsbyname.3 getvfsent.3 \ - glob.3 initgroups.3 isinf.3 \ - ldexp.3 lockf.3 modf.3 msgctl.3 msgget.3 msgrcv.3 msgsnd.3 \ - nice.3 nlist.3 pause.3 popen.3 psignal.3 pwcache.3 \ - raise.3 rand48.3 rfork_thread.3 \ - scandir.3 setjmp.3 setmode.3 \ - siginterrupt.3 signal.3 sigsetops.3 sleep.3 stringlist.3 \ - strtofflags.3 sysconf.3 sysctl.3 syslog.3 tcgetpgrp.3 \ - tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 time.3 times.3 timezone.3 \ - ttyname.3 tzset.3 ualarm.3 uname.3 unvis.3 usleep.3 utime.3 \ - valloc.3 vis.3 + +MAN3 += arc4random.3 confstr.3 devname.3 directory.3 fts.3 \ + getdomainname.3 getfsent.3 getgrent.3 getgrouplist.3 getloadavg.3 \ + getnetgrent.3 getobjformat.3 getpeereid.3 getpwent.3 getttyent.3 \ + getusershell.3 getvfsbyname.3 glob.3 initgroups.3 isinf.3 \ + malloc.3 nlist.3 pwcache.3 setjmp.3 sigsetops.3 \ + strtofflags.3 sysconf.3 syslog.3 tcgetpgrp.3 tcsendbreak.3 \ + tcsetattr.3 tcsetpgrp.3 tzset.3 uname.3 valloc.3 intro.3 + +.include "Makefile.fbsd_begin" +FBSDMAN3= alarm.3 basename.3 clock.3 ctermid.3 daemon.3 dirname.3 err.3 exec.3 \ + fmtcheck.3 fnmatch.3 ftok.3 getbsize.3 getcap.3 getcwd.3 \ + gethostname.3 getmntinfo.3 getpagesize.3 getpass.3 getprogname.3 \ + lockf.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 sleep.3 \ + stringlist.3 sysctl.3 time.3 times.3 timezone.3 ttyname.3 ualarm.3 \ + ulimit.3 unvis.3 usleep.3 utime.3 vis.3 +.include "Makefile.fbsd_end" MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3 MLINKS+=ctermid.3 ctermid_r.3 MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \ - directory.3 readdir.3 directory.3 rewinddir.3 directory.3 seekdir.3 \ - directory.3 telldir.3 + directory.3 readdir.3 directory.3 readdir_r.3 directory.3 rewinddir.3 \ + directory.3 seekdir.3 directory.3 telldir.3 MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errc.3 err.3 errx.3 \ err.3 verr.3 err.3 verrc.3 err.3 verrx.3 err.3 vwarn.3 err.3 vwarnc.3 \ err.3 vwarnx.3 err.3 warnc.3 err.3 warn.3 err.3 warnx.3 -MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 exect.3 \ +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 @@ -93,17 +79,17 @@ MLINKS+=getgrent.3 endgrent.3 getgrent.3 getgrgid.3 getgrent.3 getgrnam.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+=getvfsent.3 endvfsent.3 getvfsent.3 getvfsbytype.3 \ - getvfsent.3 setvfsent.3 getvfsent.3 vfsisloadable.3 \ - getvfsent.3 vfsload.3 MLINKS+=glob.3 globfree.3 MLINKS+=isinf.3 isnan.3 isinf.3 isnanf.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 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 @@ -135,5 +121,4 @@ 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+=readdir.3 readdir_r.3 .endif diff --git a/gen/OSSystemInfo.c b/gen/OSSystemInfo.c new file mode 100644 index 0000000..42f1691 --- /dev/null +++ b/gen/OSSystemInfo.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 + +static int osi_oid[2] = {-1, 0}; + +bool +OSSystemInfo(int selector, unsigned long long *resultp) +{ + int oid[3]; + size_t size; + + /* + * Check cached OID, look it up if we haven't already. + * + * NB. Whilst this isn't strictly thread safe, since the + * result as written by any thread will be the same + * there is no actual risk of corruption. + */ + if (osi_oid[0] == -1) { + size = 2; + if (sysctlnametomib("hw.systeminfo", &osi_oid, &size) || + (size != 2)) + return(false); + } + + /* build OID */ + oid[0] = osi_oid[0]; + oid[1] = osi_oid[1]; + oid[2] = selector; + + /* make the call */ + size = sizeof(*resultp); + if (sysctl(oid, 3, resultp, &size, NULL, 0) || + (size != sizeof(*resultp))) + return(false); + + return(true); +} + diff --git a/gen/arc4random.c b/gen/arc4random.c index 0dce7ef..c761a71 100644 --- a/gen/arc4random.c +++ b/gen/arc4random.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 $ */ /* diff --git a/gen/strchr.c b/gen/cache.c similarity index 67% rename from gen/strchr.c rename to gen/cache.c index 546fa44..d6bbe5d 100644 --- a/gen/strchr.c +++ b/gen/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,23 +22,22 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1992, 1995 NeXT Computer, Inc. All rights reserved. - * - * File: libc/gen/strchr.c - * - * This file contains machine independent code for string index - * - */ -#import +/* cache control */ -/* This routine needs to be optimized. */ +#include +#include +#include +#include -char *strchr(const char *s, int c) -{ - const char ch = c; +static const unsigned int kCacheOptionsSyncForExecution = 0x1; +extern void sys_icache_invalidate(void *, size_t); - for ( ; *s != ch; s++) - if (*s == '\0') - return 0; - return (char *)s; +int +sys_cache_control(unsigned int options, caddr_t start, size_t len) +{ + if (options == kCacheOptionsSyncForExecution) { + sys_icache_invalidate(start, len); + return 0; + } + return ENOTSUP; } diff --git a/gen/crypt.c b/gen/crypt.c index 617b38e..3eb4d10 100644 --- a/gen/crypt.c +++ b/gen/crypt.c @@ -130,6 +130,7 @@ #define STATIC static #endif STATIC void init_des(), init_perm(), permute(); +STATIC int des_cipher(), des_setkey(); #ifdef DEBUG STATIC prtab(); #endif @@ -394,46 +395,54 @@ static unsigned char PC2[] = { /* permuted choice table 2 */ }; static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */ - /* S[1] */ + { /* S[1] */ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, - /* S[2] */ + }, + { /* S[2] */ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, - /* S[3] */ + }, + { /* S[3] */ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, - /* S[4] */ + }, + { /* S[4] */ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, - /* S[5] */ + }, + { /* S[5] */ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, - /* S[6] */ + }, + { /* S[6] */ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, - /* S[7] */ + }, + { /* S[7] */ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, - /* S[8] */ + }, + { /* S[8] */ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, + }, }; static unsigned char P32Tr[] = { /* 32-bit permutation function */ diff --git a/gen/ctime.c b/gen/ctime.c deleted file mode 100644 index 0f5753c..0000000 --- a/gen/ctime.c +++ /dev/null @@ -1,1402 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Arthur David Olson of the National Cancer Institute. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -/* -** 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 -#include -#include -#include -#include -#include -#include -#include - -#ifdef __STDC__ -#include - -#define P(s) s -#define alloc_size_t size_t -#define qsort_size_t size_t -#define fread_size_t size_t -#define fwrite_size_t size_t - -#else /* !defined __STDC__ */ - -#define P(s) () - -typedef char * genericptr_t; -typedef unsigned alloc_size_t; -typedef int qsort_size_t; -typedef int fread_size_t; -typedef int fwrite_size_t; - -extern char * calloc(); -extern char * malloc(); -extern char * realloc(); -extern char * getenv(); - -#endif /* !defined __STDC__ */ - -extern time_t time(); - -#define ACCESS_MODE O_RDONLY -#define OPEN_MODE O_RDONLY - -#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 */ - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif /* !defined TRUE */ - -static const char GMT[] = "GMT"; - -struct ttinfo { /* time type information */ - long tt_gmtoff; /* GMT 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 */ -}; - -struct lsinfo { /* leap second information */ - time_t ls_trans; /* transition time */ - long ls_corr; /* correction to apply */ -}; - -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[(TZ_MAX_CHARS + 1 > sizeof GMT) ? - TZ_MAX_CHARS + 1 : sizeof GMT]; - 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 */ - -/* -** Prototypes for static functions. -*/ - -static long detzcode P((const char * codep)); -static const char * getzname P((const char * strp)); -static const char * getnum P((const char * strp, int * nump, int min, - int max)); -static const char * getsecs P((const char * strp, long * secsp)); -static const char * getoffset P((const char * strp, long * offsetp)); -static const char * getrule P((const char * strp, struct rule * rulep)); -static void gmtload P((struct state * sp)); -static void gmtsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void localsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void normalize P((int * tensptr, int * unitsptr, int base)); -static void settzname P((void)); -static time_t time1 P((struct tm * tmp, void (* funcp)(), - long offset)); -static time_t time2 P((struct tm *tmp, void (* funcp)(), - long offset, int * okayp)); -static void timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); -static time_t transtime P((time_t janfirst, int year, - const struct rule * rulep, long offset)); -static int tzload P((const char * name, struct state * sp)); -static int tzparse P((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 */ - -static int lcl_is_set; -static int gmt_is_set; - -char * tzname[2] = { - WILDABBR, - WILDABBR -}; - -#ifdef USG_COMPAT -time_t timezone = 0; -int daylight = 0; -#endif /* defined USG_COMPAT */ - -#ifdef ALTZONE -time_t altzone = 0; -#endif /* defined ALTZONE */ - -static long -detzcode(codep) -const char * const codep; -{ - register long result; - register int i; - - result = 0; - for (i = 0; i < 4; ++i) - result = (result << 8) | (codep[i] & 0xff); - return result; -} - -static void -settzname() -{ - register const struct state * const sp = lclptr; - register int i; - - tzname[0] = WILDABBR; - tzname[1] = WILDABBR; -#ifdef USG_COMPAT - daylight = 0; - timezone = 0; -#endif /* defined USG_COMPAT */ -#ifdef ALTZONE - altzone = 0; -#endif /* defined ALTZONE */ -#ifdef ALL_STATE - if (sp == NULL) { - tzname[0] = tzname[1] = GMT; - return; - } -#endif /* defined ALL_STATE */ - for (i = 0; i < sp->typecnt; ++i) { - register const struct ttinfo * const ttisp = &sp->ttis[i]; - - tzname[ttisp->tt_isdst] = - (char *) &sp->chars[ttisp->tt_abbrind]; -#ifdef USG_COMPAT - if (ttisp->tt_isdst) - daylight = 1; - if (i == 0 || !ttisp->tt_isdst) - 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) { - register const struct ttinfo * const ttisp = - &sp->ttis[sp->types[i]]; - - tzname[ttisp->tt_isdst] = - (char *) &sp->chars[ttisp->tt_abbrind]; - } -} - -static int -tzload(name, sp) -register const char * name; -register struct state * const sp; -{ - register const char * p; - register int i; - register int fid; - - if (name == NULL && (name = TZDEFAULT) == NULL) - return -1; - { - char fullname[FILENAME_MAX + 1]; - - if (name[0] == ':') - ++name; - if (name[0] != '/') { - if ((p = TZDIR) == NULL) - return -1; - if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) - return -1; - (void) strcpy(fullname, p); - (void) strcat(fullname, "/"); - (void) strcat(fullname, name); - name = fullname; - } - if ((fid = open(name, OPEN_MODE)) == -1) - return -1; - } - { - register const struct tzhead * tzhp; - char buf[sizeof *sp + sizeof *tzhp]; - int ttisstdcnt; - - i = read(fid, buf, sizeof buf); - if (close(fid) != 0 || i < sizeof *tzhp) - return -1; - tzhp = (struct tzhead *) buf; - ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt); - sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt); - sp->timecnt = (int) detzcode(tzhp->tzh_timecnt); - sp->typecnt = (int) detzcode(tzhp->tzh_typecnt); - sp->charcnt = (int) detzcode(tzhp->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)) - return -1; - if (i < sizeof *tzhp + - sp->timecnt * (4 + sizeof (char)) + - sp->typecnt * (4 + 2 * sizeof (char)) + - sp->charcnt * sizeof (char) + - sp->leapcnt * 2 * 4 + - ttisstdcnt * sizeof (char)) - return -1; - p = buf + sizeof *tzhp; - 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) { - register 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) { - register 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) { - register 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; - } - } - } - 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) -register const char * strp; -{ - register char c; - - while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' && - c != '+') - ++strp; - 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) -register const char * strp; -int * const nump; -const int min; -const int max; -{ - register char c; - register int num; - - if (strp == NULL || !isdigit(*strp)) - return NULL; - num = 0; - while ((c = *strp) != '\0' && isdigit(c)) { - num = num * 10 + (c - '0'); - if (num > max) - return NULL; /* illegal value */ - ++strp; - } - 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) -register const char * strp; -long * const secsp; -{ - int num; - - strp = getnum(strp, &num, 0, HOURSPERDAY); - if (strp == NULL) - return NULL; - *secsp = num * SECSPERHOUR; - if (*strp == ':') { - ++strp; - strp = getnum(strp, &num, 0, MINSPERHOUR - 1); - if (strp == NULL) - return NULL; - *secsp += num * SECSPERMIN; - if (*strp == ':') { - ++strp; - strp = getnum(strp, &num, 0, SECSPERMIN - 1); - 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) -register const char * strp; -long * const offsetp; -{ - register int neg; - - if (*strp == '-') { - neg = 1; - ++strp; - } else if (isdigit(*strp) || *strp++ == '+') - neg = 0; - else return NULL; /* illegal offset */ - 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; -register 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 (isdigit(*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 GMT, in a year, the -** year, a rule, and the offset from GMT 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; -register const struct rule * const rulep; -const long offset; -{ - register int leapyear; - register time_t value; - register int i; - int d, m1, yy0, yy1, yy2, dow; - - 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 GMT 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 GMT. - */ - 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; -register struct state * const sp; -const int lastditch; -{ - const char * stdname; - const char * dstname; - int stdlen; - int dstlen; - long stdoffset; - long dstoffset; - register time_t * atp; - register unsigned char * typep; - register char * cp; - register int load_result; - - stdname = name; - if (lastditch) { - stdlen = strlen(name); /* length of standard zone name */ - name += stdlen; - if (stdlen >= sizeof sp->chars) - stdlen = (sizeof sp->chars) - 1; - } else { - name = getzname(name); - stdlen = name - stdname; - if (stdlen < 3) - return -1; - } - if (*name == '\0') - return -1; - else { - name = getoffset(name, &stdoffset); - if (name == NULL) - return -1; - } - load_result = tzload(TZDEFRULES, sp); - if (load_result != 0) - sp->leapcnt = 0; /* so, we're off a little */ - if (*name != '\0') { - dstname = name; - name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ - 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 == ',' || *name == ';') { - struct rule start; - struct rule end; - register int year; - register 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 { - int sawstd; - int sawdst; - long stdfix; - long dstfix; - long oldfix; - int isdst; - register int i; - - if (*name != '\0') - return -1; - if (load_result != 0) - return -1; - /* - ** Compute the difference between the real and - ** prototype standard and summer time offsets - ** from GMT, and put the real standard and summer - ** time offsets into the rules in place of the - ** prototype offsets. - */ - sawstd = FALSE; - sawdst = FALSE; - stdfix = 0; - dstfix = 0; - for (i = 0; i < sp->typecnt; ++i) { - if (sp->ttis[i].tt_isdst) { - oldfix = dstfix; - dstfix = - sp->ttis[i].tt_gmtoff + dstoffset; - if (sawdst && (oldfix != dstfix)) - return -1; - sp->ttis[i].tt_gmtoff = -dstoffset; - sp->ttis[i].tt_abbrind = stdlen + 1; - sawdst = TRUE; - } else { - oldfix = stdfix; - stdfix = - sp->ttis[i].tt_gmtoff + stdoffset; - if (sawstd && (oldfix != stdfix)) - return -1; - sp->ttis[i].tt_gmtoff = -stdoffset; - sp->ttis[i].tt_abbrind = 0; - sawstd = TRUE; - } - } - /* - ** Make sure we have both standard and summer time. - */ - if (!sawdst || !sawstd) - return -1; - /* - ** Now correct the transition times by shifting - ** them by the difference between the real and - ** prototype offsets. Note that this difference - ** can be different in standard and summer time; - ** the prototype probably has a 1-hour difference - ** between standard and summer time, but a different - ** difference can be specified in TZ. - */ - isdst = FALSE; /* we start in standard time */ - for (i = 0; i < sp->timecnt; ++i) { - register const struct ttinfo * ttisp; - - /* - ** 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. - */ - ttisp = &sp->ttis[sp->types[i]]; - sp->ats[i] += - (isdst && !ttisp->tt_ttisstd) ? - dstfix : stdfix; - isdst = ttisp->tt_isdst; - } - } - } 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 (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); -} - -void -tzset() -{ - register const char * name; - void tzsetwall(); - - name = getenv("TZ"); - if (name == NULL) { - tzsetwall(); - return; - } - lcl_is_set = TRUE; -#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->ttis[0].tt_gmtoff = 0; - lclptr->ttis[0].tt_abbrind = 0; - (void) strcpy(lclptr->chars, GMT); - } else if (tzload(name, lclptr) != 0) - if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) - (void) gmtload(lclptr); - settzname(); -} - -void -tzsetwall() -{ - lcl_is_set = TRUE; -#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); - settzname(); -} - -/* -** 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*/ -static void -localsub(timep, offset, tmp) -const time_t * const timep; -const long offset; -struct tm * const tmp; -{ - register struct state * sp; - register const struct ttinfo * ttisp; - register int i; - const time_t t = *timep; - - if (!lcl_is_set) - tzset(); - sp = lclptr; -#ifdef ALL_STATE - if (sp == NULL) { - gmtsub(timep, offset, tmp); - return; - } -#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); - */ - timesub(&t, ttisp->tt_gmtoff, sp, tmp); - tmp->tm_isdst = ttisp->tt_isdst; - tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind]; - tmp->tm_zone = &sp->chars[ttisp->tt_abbrind]; -} - -struct tm * -localtime(timep) -const time_t * const timep; -{ - static struct tm tm; - - localsub(timep, 0L, &tm); - return &tm; -} - -/* -** gmtsub is to gmtime as localsub is to localtime. -*/ - -static void -gmtsub(timep, offset, tmp) -const time_t * const timep; -const long offset; -struct tm * const tmp; -{ - if (!gmt_is_set) { - gmt_is_set = TRUE; -#ifdef ALL_STATE - gmtptr = (struct state *) malloc(sizeof *gmtptr); - if (gmtptr != NULL) -#endif /* defined ALL_STATE */ - gmtload(gmtptr); - } - timesub(timep, offset, gmtptr, tmp); - /* - ** Could get fancy here and deliver something such as - ** "GMT+xxxx" or "GMT-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 = GMT; - else tmp->TM_ZONE = gmtptr->chars; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE - tmp->tm_zone = gmtptr->chars; -#endif /* State Farm */ - } -} - -struct tm * -gmtime(timep) -const time_t * const timep; -{ - static struct tm tm; - - gmtsub(timep, 0L, &tm); - return &tm; -} - -static void -timesub(timep, offset, sp, tmp) -const time_t * const timep; -const long offset; -register const struct state * const sp; -register struct tm * const tmp; -{ - register const struct lsinfo * lp; - register long days; - register long rem; - register int y; - register int yleap; - register const int * ip; - register long corr; - register int hit; - register int i; - - corr = 0; - hit = FALSE; -#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); - 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 /* 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); - tmp->tm_sec = (int) (rem % SECSPERMIN); - if (hit) - /* - ** A positive leap second requires a special - ** representation. This uses "... ??:59:60". - */ - ++(tmp->tm_sec); - tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); - if (tmp->tm_wday < 0) - tmp->tm_wday += DAYSPERWEEK; - y = EPOCH_YEAR; - if (days >= 0) - for ( ; ; ) { - yleap = isleap(y); - if (days < (long) year_lengths[yleap]) - break; - ++y; - days = days - (long) year_lengths[yleap]; - } - else do { - --y; - yleap = isleap(y); - days = days + (long) year_lengths[yleap]; - } while (days < 0); - tmp->tm_year = y - TM_YEAR_BASE; - 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; - tmp->tm_gmtoff = offset; -} - -/* -** A la X3J11 -*/ - -char * -asctime(timeptr) -register const struct tm * timeptr; -{ - static const char wday_name[DAYSPERWEEK][3] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static const char mon_name[MONSPERYEAR][3] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - static char result[26]; - - (void) sprintf(result, "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n", - wday_name[timeptr->tm_wday], - mon_name[timeptr->tm_mon], - timeptr->tm_mday, timeptr->tm_hour, - timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); - return result; -} - -char * -ctime(timep) -const time_t * const timep; -{ - return asctime(localtime(timep)); -} - -/* -** 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. (mtxinu!kridle now). -** 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 */ - -static void -normalize(tensptr, unitsptr, base) -int * const tensptr; -int * const unitsptr; -const int base; -{ - if (*unitsptr >= base) { - *tensptr += *unitsptr / base; - *unitsptr %= base; - } else if (*unitsptr < 0) { - *tensptr -= 1 + (-(*unitsptr + 1)) / base; - *unitsptr = base - 1 - (-(*unitsptr + 1)) % base; - } -} - -static int -tmcomp(atmp, btmp) -register const struct tm * const atmp; -register const struct tm * const btmp; -{ - register 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 -time2(tmp, funcp, offset, okayp) -struct tm * const tmp; -void (* const funcp)(); -const long offset; -int * const okayp; -{ - register const struct state * sp; - register int dir; - register int bits; - register int i, j ; - register int saved_seconds; - time_t newt; - time_t t; - struct tm yourtm, mytm; - - *okayp = FALSE; - yourtm = *tmp; - if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0) - normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN); - normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR); - normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY); - normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR); - while (yourtm.tm_mday <= 0) { - --yourtm.tm_year; - yourtm.tm_mday += - year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)]; - } - while (yourtm.tm_mday > DAYSPERLYEAR) { - yourtm.tm_mday -= - year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)]; - ++yourtm.tm_year; - } - for ( ; ; ) { - i = mon_lengths[isleap(yourtm.tm_year + - TM_YEAR_BASE)][yourtm.tm_mon]; - if (yourtm.tm_mday <= i) - break; - yourtm.tm_mday -= i; - if (++yourtm.tm_mon >= MONSPERYEAR) { - yourtm.tm_mon = 0; - ++yourtm.tm_year; - } - } - saved_seconds = yourtm.tm_sec; - yourtm.tm_sec = 0; - /* - ** Calculate the number of magnitude bits in a time_t - ** (this works regardless of whether time_t is - ** signed or unsigned, though lint complains if unsigned). - */ - for (bits = 0, t = 1; t > 0; ++bits, t <<= 1) - ; - /* - ** If time_t is signed, then 0 is the median value, - ** if time_t is unsigned, then 1 << bits is median. - */ - t = (t < 0) ? 0 : ((time_t) 1 << bits); - for ( ; ; ) { - (*funcp)(&t, offset, &mytm); - dir = tmcomp(&mytm, &yourtm); - if (dir != 0) { - if (bits-- < 0) - return WRONG; - if (bits < 0) - --t; - else if (dir > 0) - t -= (time_t) 1 << bits; - else t += (time_t) 1 << bits; - continue; - } - 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. - */ - sp = (const struct state *) - ((funcp == localsub) ? lclptr : gmtptr); -#ifdef ALL_STATE - if (sp == NULL) - return WRONG; -#endif /* defined ALL_STATE */ - for (i = 0; i < sp->typecnt; ++i) { - if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) - continue; - for (j = 0; j < sp->typecnt; ++j) { - if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) - continue; - newt = t + sp->ttis[j].tt_gmtoff - - sp->ttis[i].tt_gmtoff; - (*funcp)(&newt, offset, &mytm); - 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: - t += saved_seconds; - (*funcp)(&t, offset, tmp); - *okayp = TRUE; - return t; -} - -static time_t -time1(tmp, funcp, offset) -struct tm * const tmp; -void (* const funcp)(); -const long offset; -{ - register time_t t; - register const struct state * sp; - register int samei, otheri; - int okay; - - if (tmp->tm_isdst > 1) - tmp->tm_isdst = 1; - t = time2(tmp, funcp, offset, &okay); - if (okay || tmp->tm_isdst < 0) - return t; - /* - ** 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 = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr); -#ifdef ALL_STATE - if (sp == NULL) - return WRONG; -#endif /* defined ALL_STATE */ - for (samei = 0; samei < sp->typecnt; ++samei) { - if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) - continue; - for (otheri = 0; otheri < sp->typecnt; ++otheri) { - 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); - 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; -} - -time_t -mktime(tmp) -struct tm * const tmp; -{ - return time1(tmp, localsub, 0L); -} diff --git a/gen/devname.c b/gen/devname.c index e8a4690..3edcabd 100644 --- a/gen/devname.c +++ b/gen/devname.c @@ -67,6 +67,7 @@ #include #include #include +#include char * devname(dev, type) diff --git a/gen/disklabel.c b/gen/disklabel.c index 68b8a4f..5058b93 100644 --- a/gen/disklabel.c +++ b/gen/disklabel.c @@ -71,8 +71,10 @@ #include #include -static int error __P((int)); -static int gettype __P((char *, char **)); +#ifdef unused +static int error(int); +#endif // unused +static int gettype(char *, char **); struct disklabel * getdiskbyname(name) @@ -192,6 +194,7 @@ gettype(t, names) return (0); } +#ifdef unused static int error(err) int err; @@ -205,3 +208,4 @@ error(err) (void)write(STDERR_FILENO, p, strlen(p)); (void)write(STDERR_FILENO, "\n", 1); } +#endif // unused diff --git a/gen/errlst.c b/gen/errlst.c index bb4e862..91fa2f0 100644 --- a/gen/errlst.c +++ b/gen/errlst.c @@ -168,9 +168,12 @@ const char *const sys_errlist[] = { "Bad executable (or shared library)", /* 85 - EBADEXEC */ "Bad CPU type in executable", /* 86 - EBADARCH */ "Shared library version mismatch", /* 87 - ESHLIBVERS */ - "Malformed Mach-o file" /* 88 - EBADMACHO */ + "Malformed Mach-o file", /* 88 - EBADMACHO */ + "Operation canceled", /* 89 - ECANCELED */ + "Identifier removed", /* 90 - EIDRM */ + "No message of desired type", /* 91 - ENOMSG */ + "Illegal byte sequence", /* 92 - EILSEQ */ + "Attribute not found", /* 93 - ENOATTR */ }; -int errno; - const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); diff --git a/gen/exec.c b/gen/exec.c deleted file mode 100644 index 606ff40..0000000 --- a/gen/exec.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __STDC__ -#include -#else -#include -#endif - -#if defined(__APPLE__) -#include -#define environ (*_NSGetEnviron()) -#else -extern char **environ; -#endif - -int -#ifdef __STDC__ -execl(const char *name, const char *arg, ...) -#else -execl(name, arg, va_alist) - const char *name; - const char *arg; - va_dcl -#endif -{ - va_list ap; - char **argv; - int n; - -#ifdef __STDC__ - va_start(ap, arg); -#else - va_start(ap); -#endif - 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); - } -#ifdef __STDC__ - va_start(ap, arg); -#else - va_start(ap); -#endif - n = 1; - argv[0] = (char *)arg; - while ((argv[n] = va_arg(ap, char *)) != NULL) - n++; - va_end(ap); - return (execve(name, argv, environ)); -} - -int -#ifdef __STDC__ -execle(const char *name, const char *arg, ...) -#else -execle(name, arg, va_alist) - const char *name; - const char *arg; - va_dcl -#endif -{ - va_list ap; - char **argv, **envp; - int n; - -#ifdef __STDC__ - va_start(ap, arg); -#else - va_start(ap); -#endif - 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); - } -#ifdef __STDC__ - va_start(ap, arg); -#else - va_start(ap); -#endif - 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 -#ifdef __STDC__ -execlp(const char *name, const char *arg, ...) -#else -execlp(name, arg, va_alist) - const char *name; - const char *arg; - va_dcl -#endif -{ - va_list ap; - char **argv; - int n; - -#ifdef __STDC__ - va_start(ap, arg); -#else - va_start(ap); -#endif - 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); - } -#ifdef __STDC__ - va_start(ap, arg); -#else - va_start(ap); -#endif - 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(name, argv) - const char *name; - char * const *argv; -{ - char **memp; - register int cnt, lp, ln; - register char *p; - int eacces = 0, etxtbsy = 0; - char *bp, *cur, *path, buf[MAXPATHLEN]; - - /* - * Do not allow null name - */ - if (name == NULL || *name == '\0') { - errno = ENOENT; - return (-1); - } - - /* If it's an absolute or relative path name, it's easy. */ - if (strchr(name, '/')) { - bp = (char *)name; - cur = path = NULL; - goto retry; - } - bp = buf; - - /* Get the path we're searching. */ - if (!(path = getenv("PATH"))) - path = _PATH_DEFPATH; - cur = alloca(strlen(path) + 1); - if (cur == NULL) { - errno = ENOMEM; - return (-1); - } - strcpy(cur, path); - path = cur; - while ((p = strsep(&cur, ":"))) { - /* - * It's a SHELL path -- double, leading and trailing colons - * mean the current directory. - */ - if (!*p) { - 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)) { - struct iovec iov[3]; - - iov[0].iov_base = "execvp: "; - iov[0].iov_len = 8; - iov[1].iov_base = p; - iov[1].iov_len = lp; - iov[2].iov_base = ": path too long\n"; - iov[2].iov_len = 16; - (void)writev(STDERR_FILENO, iov, 3); - 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) - 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; - case EACCES: - eacces = 1; - break; - default: - goto done; - } - } - if (eacces) - errno = EACCES; - else if (!errno) - errno = ENOENT; -done: - return (-1); -} diff --git a/gen/fstab.c b/gen/fstab.c deleted file mode 100644 index 1041e68..0000000 --- a/gen/fstab.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 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 -#include -#include -#include -#include -#include - -static FILE *_fs_fp; -static struct fstab _fs_fstab; - -static error __P((int)); -static fstabscan __P((void)); - -static -fstabscan() -{ - register char *cp; -#define MAXLINELENGTH 1024 - static char *line = NULL; - char subline[MAXLINELENGTH]; - int typexx; - - if( line == NULL ) { - line = malloc(MAXLINELENGTH); - if( line == NULL ) - return(1); - } - - for (;;) { - if (!(cp = fgets(line, sizeof(line), _fs_fp))) - return(0); -/* OLD_STYLE_FSTAB */ - if (!strpbrk(cp, " \t")) { - _fs_fstab.fs_spec = strtok(cp, ":\n"); - _fs_fstab.fs_file = strtok((char *)NULL, ":\n"); - _fs_fstab.fs_type = strtok((char *)NULL, ":\n"); - if (_fs_fstab.fs_type) { - if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) - continue; - _fs_fstab.fs_mntops = _fs_fstab.fs_type; - _fs_fstab.fs_vfstype = - strcmp(_fs_fstab.fs_type, FSTAB_SW) ? - "ufs" : "swap"; - if (cp = strtok((char *)NULL, ":\n")) { - _fs_fstab.fs_freq = atoi(cp); - if (cp = strtok((char *)NULL, ":\n")) { - _fs_fstab.fs_passno = atoi(cp); - return(1); - } - } - } - goto bad; - } -/* OLD_STYLE_FSTAB */ - _fs_fstab.fs_spec = strtok(cp, " \t\n"); - if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') - continue; - _fs_fstab.fs_file = strtok((char *)NULL, " \t\n"); - _fs_fstab.fs_vfstype = strtok((char *)NULL, " \t\n"); - _fs_fstab.fs_mntops = strtok((char *)NULL, " \t\n"); - if (_fs_fstab.fs_mntops == NULL) - goto bad; - _fs_fstab.fs_freq = 0; - _fs_fstab.fs_passno = 0; - if ((cp = strtok((char *)NULL, " \t\n")) != NULL) { - _fs_fstab.fs_freq = atoi(cp); - if ((cp = strtok((char *)NULL, " \t\n")) != NULL) - _fs_fstab.fs_passno = atoi(cp); - } - strcpy(subline, _fs_fstab.fs_mntops); - for (typexx = 0, cp = strtok(subline, ","); cp; - cp = strtok((char *)NULL, ",")) { - if (strlen(cp) != 2) - continue; - if (!strcmp(cp, FSTAB_RW)) { - _fs_fstab.fs_type = FSTAB_RW; - break; - } - if (!strcmp(cp, FSTAB_RQ)) { - _fs_fstab.fs_type = FSTAB_RQ; - break; - } - if (!strcmp(cp, FSTAB_RO)) { - _fs_fstab.fs_type = FSTAB_RO; - break; - } - if (!strcmp(cp, FSTAB_SW)) { - _fs_fstab.fs_type = FSTAB_SW; - break; - } - if (!strcmp(cp, FSTAB_XX)) { - _fs_fstab.fs_type = FSTAB_XX; - typexx++; - break; - } - } - if (typexx) - continue; - if (cp != NULL) - return(1); - -bad: /* no way to distinguish between EOF and syntax error */ - error(EFTYPE); - } - /* NOTREACHED */ -} - -struct fstab * -getfsent() -{ - if (!_fs_fp && !setfsent() || !fstabscan()) - return((struct fstab *)NULL); - return(&_fs_fstab); -} - -struct fstab * -getfsspec(name) - register const char *name; -{ - if (setfsent()) - while (fstabscan()) - if (!strcmp(_fs_fstab.fs_spec, name)) - return(&_fs_fstab); - return((struct fstab *)NULL); -} - -struct fstab * -getfsfile(name) - register const char *name; -{ - if (setfsent()) - while (fstabscan()) - if (!strcmp(_fs_fstab.fs_file, name)) - return(&_fs_fstab); - return((struct fstab *)NULL); -} - -setfsent() -{ - if (_fs_fp) { - rewind(_fs_fp); - return(1); - } - if (_fs_fp = fopen(_PATH_FSTAB, "r")) - return(1); - error(errno); - return(0); -} - -void -endfsent() -{ - if (_fs_fp) { - (void)fclose(_fs_fp); - _fs_fp = NULL; - } -} - -static -error(err) - int err; -{ - char *p; - - (void)write(STDERR_FILENO, "fstab: ", 7); - (void)write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1); - (void)write(STDERR_FILENO, ": ", 1); - p = strerror(err); - (void)write(STDERR_FILENO, p, strlen(p)); - (void)write(STDERR_FILENO, "\n", 1); -} diff --git a/gen/fts.c b/gen/fts.c index 1f29f44..8db8393 100644 --- a/gen/fts.c +++ b/gen/fts.c @@ -67,15 +67,15 @@ #include #include -static FTSENT *fts_alloc __P((FTS *, char *, int)); -static FTSENT *fts_build __P((FTS *, int)); -static void fts_lfree __P((FTSENT *)); -static void fts_load __P((FTS *, FTSENT *)); -static size_t fts_maxarglen __P((char * const *)); -static void fts_padjust __P((FTS *, void *)); -static int fts_palloc __P((FTS *, size_t)); -static FTSENT *fts_sort __P((FTS *, FTSENT *, int)); -static u_short fts_stat __P((FTS *, FTSENT *, int)); +static FTSENT *fts_alloc(FTS *, char *, int); +static FTSENT *fts_build(FTS *, int); +static void fts_lfree(FTSENT *); +static void fts_load(FTS *, FTSENT *); +static size_t fts_maxarglen(char * const *); +static void fts_padjust(FTS *, void *); +static int fts_palloc(FTS *, size_t); +static FTSENT *fts_sort(FTS *, FTSENT *, int); +static u_short fts_stat(FTS *, FTSENT *, int); #define ISDOT(a) (a[0] == '.' && (!a[1] || a[1] == '.' && !a[2])) diff --git a/gen/getdomainname.3 b/gen/getdomainname.3 index bb2b8a1..19aa714 100644 --- a/gen/getdomainname.3 +++ b/gen/getdomainname.3 @@ -38,7 +38,7 @@ .Sh NAME .Nm getdomainname , .Nm setdomainname -.Nd get/set domain name of current host +.Nd get/set NIS domain name of current host .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -49,7 +49,7 @@ .Fn setdomainname "const char *name" "int namelen" .Sh DESCRIPTION .Fn Getdomainname -returns the standard domain name for the current processor, as +returns the standard NIS domain name for the current host, as previously set by .Fn setdomainname . The parameter @@ -60,7 +60,7 @@ array. The returned name is null-terminated unless insufficient space is provided. .Pp .Fn Setdomainname -sets the domain name of the host machine to be +sets the NIS domain name of the host machine to be .Fa name , which has length .Fa namelen . diff --git a/gen/getgrent.3 b/gen/getgrent.3 index 6b12306..4dd70b5 100644 --- a/gen/getgrent.3 +++ b/gen/getgrent.3 @@ -152,8 +152,7 @@ group database file .Sh SEE ALSO .Xr getpwent 3 , .Xr yp 4 , -.Xr group 5 , -.Xr nsswitch.conf 5 +.Xr group 5 .Sh HISTORY The functions .Fn endgrent , @@ -197,7 +196,3 @@ and .Fn setgrent are fairly useless in a networked environment and should be avoided, if possible. -.Fn getgrent -makes no attempt to suppress duplicate information if multiple -sources are specified in -.Xr nsswitch.conf 5 . diff --git a/gen/getgrouplist.c b/gen/getgrouplist.c deleted file mode 100644 index 758a0fa..0000000 --- a/gen/getgrouplist.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (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[] = "@(#)getgrouplist.c 8.2 (Berkeley) 12/8/94"; -#endif /* LIBC_SCCS and not lint */ - -/* - * get credential - */ -#include -#include -#include - -int -getgrouplist(uname, agroup, groups, grpcnt) - const char *uname; - int agroup; - register int *groups; - int *grpcnt; -{ - register struct group *grp; - register struct passwd *pw; - register int i, ngroups; - int ret, maxgroups; - - ret = 0; - ngroups = 0; - maxgroups = *grpcnt; - /* - * When installing primary group, duplicate it; - * the first element of groups is the effective gid - * and will be overwritten when a setgid file is executed. - */ - groups[ngroups++] = agroup; - if (maxgroups > 1) - groups[ngroups++] = agroup; - /* - * Scan the group file to find additional groups. - */ - setgrent(); - while (grp = getgrent()) { - if (grp->gr_gid == agroup) - continue; - for (i = 0; grp->gr_mem[i]; i++) { - if (!strcmp(grp->gr_mem[i], uname)) { - if (ngroups >= maxgroups) { - ret = -1; - break; - } - groups[ngroups++] = grp->gr_gid; - break; - } - } - } - endgrent(); - *grpcnt = ngroups; - return (ret); -} diff --git a/gen/getpass.c b/gen/getpass.c deleted file mode 100644 index b7d5ca3..0000000 --- a/gen/getpass.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include -#include - -#include -#include -#include -#include - -char * -getpass(prompt) - const char *prompt; -{ - struct termios term; - register int ch; - register char *p; - FILE *fp, *outfp; - long omask; - int echo; - static char buf[_PASSWORD_LEN + 1]; - - /* - * read and write to /dev/tty if possible; else read from - * stdin and write to stderr. - */ - if ((outfp = fp = fopen(_PATH_TTY, "w+")) == NULL) { - outfp = stderr; - fp = stdin; - } - /* - * note - blocking signals isn't necessarily the - * right thing, but we leave it for now. - */ - omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP)); - (void)tcgetattr(fileno(fp), &term); - if (echo = (term.c_lflag & ECHO)) { - term.c_lflag &= ~ECHO; - (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term); - } - (void)fputs(prompt, outfp); - rewind(outfp); /* implied flush */ - for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';) - if (p < buf + _PASSWORD_LEN) - *p++ = ch; - *p = '\0'; - (void)write(fileno(outfp), "\n", 1); - if (echo) { - term.c_lflag |= ECHO; - (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term); - } - (void)sigsetmask(omask); - if (fp != stdin) - (void)fclose(fp); - return(buf); -} diff --git a/gen/getpeereid.3 b/gen/getpeereid.3 index ef07e29..c63c6ac 100644 --- a/gen/getpeereid.3 +++ b/gen/getpeereid.3 @@ -93,9 +93,9 @@ is implemented in terms of the .Xr unix 4 socket option. .Sh RETURN VALUES -.Rv -std getpeerid +.Rv -std getpeereid .Sh ERRORS -.Fn getpeerid +.Fn getpeereid fails if: .Bl -tag -width Er .It Bq Er EBADF diff --git a/gen/getpwent.3 b/gen/getpwent.3 index 6ce2003..1515c49 100644 --- a/gen/getpwent.3 +++ b/gen/getpwent.3 @@ -56,7 +56,7 @@ .Fn getpwuid "uid_t uid" .Ft int .Fn setpassent "int stayopen" -.Ft void +.Ft int .Fn setpwent void .Ft void .Fn endpwent void @@ -131,12 +131,41 @@ The function closes any open files. .Pp -These routines have been written to ``shadow'' the password file, e.g.\& +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 will contiain 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 , @@ -147,13 +176,13 @@ 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 -function returns 0 on failure and 1 on success. +and +.Fn setpwent +functions return 0 on failure and 1 on success. The .Fn endpwent -and -.Fn setpwent -functions -have no return value. +function +has no return value. .Sh FILES .Bl -tag -width /etc/master.passwd -compact .It Pa /etc/pwd.db @@ -169,7 +198,6 @@ A Version 7 format password file .Xr getlogin 2 , .Xr getgrent 3 , .Xr yp 4 , -.Xr nsswitch.conf 5 , .Xr passwd 5 , .Xr pwd_mkdb 8 , .Xr vipw 8 @@ -212,7 +240,3 @@ and .Fn setpwent are fairly useless in a networked environment and should be avoided, if possible. -.Fn getpwent -makes no attempt to suppress duplicate information if multiple -sources are specified in -.Xr nsswitch.conf 5 . diff --git a/gen/getusershell.3 b/gen/getusershell.3 index 4d8805e..2da6103 100644 --- a/gen/getusershell.3 +++ b/gen/getusershell.3 @@ -86,7 +86,6 @@ The routine returns a null pointer (0) on .Dv EOF . .Sh SEE ALSO -.Xr nsswitch.conf 5 , .Xr shells 5 .Sh HISTORY The diff --git a/gen/getusershell.c b/gen/getusershell.c index 0541369..9c25b5d 100644 --- a/gen/getusershell.c +++ b/gen/getusershell.c @@ -72,7 +72,7 @@ static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; static char **curshell, **shells, *strings; -static char **initshells __P((void)); +static char **initshells(void); /* * Get a list of shells from _PATH_SHELLS, if it exists. diff --git a/gen/getvfsbyname.c b/gen/getvfsbyname.c index 049f52f..6d93228 100644 --- a/gen/getvfsbyname.c +++ b/gen/getvfsbyname.c @@ -60,13 +60,15 @@ #include #include #include +#include -int getvfsbyname __P((const char *, struct vfsconf *)); +int getvfsbyname(const char *, struct vfsconf *); /* * Given a filesystem name, determine if it is resident in the kernel, * and if it is resident, return its vfsconf structure. */ +int getvfsbyname(fsname, vfcp) const char *fsname; struct vfsconf *vfcp; diff --git a/gen/getvfsent.3 b/gen/getvfsent.3 deleted file mode 100644 index 7795677..0000000 --- a/gen/getvfsent.3 +++ /dev/null @@ -1,183 +0,0 @@ -.\" $FreeBSD: src/lib/libc/gen/getvfsent.3,v 1.24 2001/10/01 16:08:51 ru Exp $ -.\" Written by Garrett A. Wollman, September 1994. -.\" This manual page is in the public domain. -.\" -.Dd September 24, 1994 -.Dt GETVFSENT 3 -.Os -.Sh NAME -.Nm getvfsent , -.Nm setvfsent , -.Nm endvfsent , -.Nm vfsisloadable , -.Nm vfsload -.Nd manage virtual filesystem modules -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/param.h -.In sys/mount.h -.Ft struct ovfsconf * -.Fn getvfsent "void" -.Ft void -.Fn setvfsent "int cachelist" -.Ft void -.Fn endvfsent "void" -.Ft int -.Fn vfsisloadable "const char *name" -.Ft int -.Fn vfsload "const char *name" -.Sh DESCRIPTION -The -.Fn getvfsent -function provides convenient access to a list of installed virtual -filesystem modules managed by the kernel. It steps through the -list of filesystems one at a time. A null pointer is returned when -no more data is available. The fields in a -.Dq Li struct ovfsconf -are as follows: -.Pp -.Bl -tag -compact -width vfc_refcount -.It vfc_name -the name of the filesystem -.It vfc_index -the filesystem type number assigned by the kernel and used in calls to -.Xr mount 2 -.It vfc_refcount -the number of references to this filesystem -(usually the number of mounts, but one greater for filesystems which -cannot be unloaded or which are statically linked into the kernel) -.It vfc_flags -flag bits -.El -.Pp -The flags are defined as follows: -.Pp -.Bl -tag -width VFCF_SYNTHETIC -compact -.It Dv VFCF_STATIC -statically compiled into kernel -.It Dv VFCF_NETWORK -may get data over the network -.It Dv VFCF_READONLY -writes are not implemented -.It Dv VFCF_SYNTHETIC -data does not represent real files -.It Dv VFCF_LOOPBACK -aliases some other mounted FS -.It Dv VFCF_UNICODE -stores file names as Unicode -.El -.Pp -The -.Fn setvfsent -and -.Fn endvfsent -functions are used to control caching of the filesystem list, which is -obtained in toto from the kernel via -.Xr sysctl 3 . -If the -.Fa cachelist -parameter to -.Fn setvfsent -is non-zero, the list will be retrieved only once, upon the first call -to one of the retrieval functions, until -.Fn endvfsent -is called to clear the cache. In general, -.Fn setvfsent 1 -should be called by programs using the -.Fn getvfsent -function, and -.Fn setvfsent 0 -(which is also the default state) -should be called by programs using the -.Fn vfsload -function. -.Pp -The -.Fn vfsisloadable -function returns a non-zero value if a later call to -.Fn vfsload name -is likely to succeed. We say -.Dq likely -because -.Fn vfsisloadable -does not check any of the conditions necessary for -.Fn vfsload -to succeed. -.Pp -The -.Fn vfsload -function attempts to load a kernel module implementing filesystem -.Fa name . -It returns zero if the filesystem module was successfully located and -loaded, or non-zero otherwise. It should only be called in the -following circumstances: -.Bl -enum -.It -.Fn getvfsbyname -has been called and returned a non-zero value. -.It -.Fn vfsisloadable -has been called and returned a non-zero value. -.El -.Pp -Here is an example, taken from the source to -.Xr mount_cd9660 8 : -.Bd -literal -offset indent - -struct vfsconf *vfc; -int error; - -/* setup code here */ - -error = getvfsbyname("cd9660", &vfc); -if (error && vfsisloadable("cd9660")) { - if (vfsload("cd9660")) - err(EX_OSERR, "vfsload(cd9660)"); - endvfsent(); /* flush cache */ - error = getvfsbyname("cd9660", &vfc); -} -if (error) - errx(1, "cd9660 filesystem is not available"); - -if (mount(vfc.vfc_name, dir, mntflags, &args) < 0) - err(1, NULL); - -.Ed -.Sh RETURN VALUES -The -.Fn getvfsent -routine returns a pointer to a static data structure when -it succeeds, and returns a null pointer when it fails. On failure, -.Va errno -may be set to one of the values documented for -.Xr sysctl 3 -or -.Xr malloc 3 , -if a failure of that function was the cause; otherwise -.Va errno -will be unmodified. -.Pp -The -.Fn vfsload -function returns a non-zero value on failure, or zero on success. If -.Fn vfsload -fails, -.Va errno -may be set to one of the values documented for -.Xr kldload 2 . -.Sh SEE ALSO -.Xr kldload 2 , -.Xr mount 2 , -.Xr mount 8 -.Sh AUTHORS -.An -nosplit -The loadable filesystem support was written by -.An Garrett A. Wollman , -based on generic loadable kernel module support by -.An Terry Lambert . -.Sh HISTORY -The -.Fn getvfsent -family of functions first appeared in -.Fx 2.0 . diff --git a/gen/glob.c b/gen/glob.c deleted file mode 100644 index a9b8c6d..0000000 --- a/gen/glob.c +++ /dev/null @@ -1,867 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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) -- 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. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 0x8000 -#define M_PROTECT 0x4000 -#define M_MASK 0xffff -#define M_ASCII 0x00ff - -typedef u_short Char; - -#else - -#define M_QUOTE 0x80 -#define M_PROTECT 0x40 -#define M_MASK 0xff -#define M_ASCII 0x7f - -typedef char Char; - -#endif - - -#define CHAR(c) ((Char)((c)&M_ASCII)) -#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 compare __P((const void *, const void *)); -static void g_Ctoc __P((const Char *, char *)); -static int g_lstat __P((Char *, struct stat *, glob_t *)); -static DIR *g_opendir __P((Char *, glob_t *)); -static Char *g_strchr __P((Char *, int)); -#ifdef notdef -static Char *g_strcat __P((Char *, const Char *)); -#endif -static int g_stat __P((Char *, struct stat *, glob_t *)); -static int glob0 __P((const Char *, glob_t *)); -static int glob1 __P((Char *, glob_t *)); -static int glob2 __P((Char *, Char *, Char *, glob_t *)); -static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *)); -static int globextend __P((const Char *, glob_t *)); -static const Char * globtilde __P((const Char *, Char *, glob_t *)); -static int globexp1 __P((const Char *, glob_t *)); -static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); -static int match __P((Char *, Char *, Char *)); -#ifdef DEBUG -static void qprintf __P((const char *, Char *)); -#endif - -int -glob(pattern, flags, errfunc, pglob) - const char *pattern; - int flags, (*errfunc) __P((const char *, int)); - glob_t *pglob; -{ - const u_char *patnext; - int c; - Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; - - patnext = (u_char *) pattern; - if (!(flags & GLOB_APPEND)) { - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - if (!(flags & GLOB_DOOFFS)) - pglob->gl_offs = 0; - } - pglob->gl_flags = flags & ~GLOB_MAGCHAR; - pglob->gl_errfunc = errfunc; - pglob->gl_matchc = 0; - - bufnext = patbuf; - bufend = bufnext + MAXPATHLEN; - if (flags & GLOB_QUOTE) { - /* Protect the quoted characters. */ - while (bufnext < bufend && (c = *patnext++) != EOS) - if (c == QUOTE) { - if ((c = *patnext++) == EOS) { - c = QUOTE; - --patnext; - } - *bufnext++ = c | M_PROTECT; - } - else - *bufnext++ = c; - } - else - while (bufnext < bufend && (c = *patnext++) != EOS) - *bufnext++ = c; - *bufnext = EOS; - - if (flags & GLOB_BRACE) - return globexp1(patbuf, pglob); - else - return glob0(patbuf, pglob); -} - -/* - * 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 globexp1(pattern, pglob) - const Char *pattern; - glob_t *pglob; -{ - 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); - - while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) - if (!globexp2(ptr, pattern, pglob, &rv)) - return rv; - - return glob0(pattern, pglob); -} - - -/* - * 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) - const Char *ptr, *pattern; - glob_t *pglob; - int *rv; -{ - int i; - Char *lm, *ls; - const Char *pe, *pm, *pl; - Char patbuf[MAXPATHLEN + 1]; - - /* copy part up to the brace */ - for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) - continue; - 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); - 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); - - /* 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, pglob) - const Char *pattern; - Char *patbuf; - glob_t *pglob; -{ - struct passwd *pwd; - char *h; - const Char *p; - Char *b; - - if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) - return pattern; - - /* Copy up to the end of the string or / */ - for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH; - *h++ = *p++) - continue; - - *h = EOS; - - if (((char *) patbuf)[0] == EOS) { - /* - * handle a plain ~ or ~/ by expanding $HOME - * first and then trying the password file - */ - if ((h = getenv("HOME")) == NULL) { - if ((pwd = getpwuid(getuid())) == NULL) - return pattern; - else - h = pwd->pw_dir; - } - } - else { - /* - * Expand a ~user - */ - if ((pwd = getpwnam((char*) patbuf)) == NULL) - return pattern; - else - h = pwd->pw_dir; - } - - /* Copy the home directory */ - for (b = patbuf; *h; *b++ = *h++) - continue; - - /* Append the rest of the pattern */ - while ((*b++ = *p++) != EOS) - continue; - - 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. It is not an error - * to find no matches. - */ -static int -glob0(pattern, pglob) - const Char *pattern; - glob_t *pglob; -{ - const Char *qpatnext; - int c, err, oldpathc; - Char *bufnext, patbuf[MAXPATHLEN+1]; - - qpatnext = globtilde(pattern, patbuf, pglob); - oldpathc = pglob->gl_pathc; - bufnext = patbuf; - - /* We don't need to check for buffer overflow any more. */ - while ((c = *qpatnext++) != EOS) { - 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)) != 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 && - ((pglob->gl_flags & GLOB_NOCHECK) || - ((pglob->gl_flags & GLOB_NOMAGIC) && - !(pglob->gl_flags & GLOB_MAGCHAR)))) - return(globextend(pattern, pglob)); - else 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(strcmp(*(char **)p, *(char **)q)); -} - -static int -glob1(pattern, pglob) - Char *pattern; - glob_t *pglob; -{ - Char pathbuf[MAXPATHLEN+1]; - - /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ - if (*pattern == EOS) - return(0); - return(glob2(pathbuf, pathbuf, pattern, pglob)); -} - -/* - * 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 -glob2(pathbuf, pathend, pattern, pglob) - Char *pathbuf, *pathend, *pattern; - glob_t *pglob; -{ - 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)) - 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) == 0) && - S_ISDIR(sb.st_mode)))) { - *pathend++ = SEP; - *pathend = EOS; - } - ++pglob->gl_matchc; - return(globextend(pathbuf, pglob)); - } - - /* Find end of next segment, copy tentatively to pathend. */ - q = pathend; - p = pattern; - while (*p != EOS && *p != SEP) { - if (ismeta(*p)) - anymeta = 1; - *q++ = *p++; - } - - if (!anymeta) { /* No expansion, do next segment. */ - pathend = q; - pattern = p; - while (*pattern == SEP) - *pathend++ = *pattern++; - } else /* Need expansion, recurse. */ - return(glob3(pathbuf, pathend, pattern, p, pglob)); - } - /* NOTREACHED */ -} - -static int -glob3(pathbuf, pathend, pattern, restpattern, pglob) - Char *pathbuf, *pathend, *pattern, *restpattern; - glob_t *pglob; -{ - register 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)(); - - *pathend = EOS; - errno = 0; - - if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { - /* TODO: don't call for ENOENT or ENOTDIR? */ - if (pglob->gl_errfunc) { - g_Ctoc(pathbuf, buf); - if (pglob->gl_errfunc(buf, errno) || - pglob->gl_flags & GLOB_ERR) - return (GLOB_ABEND); - } - 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))) { - register u_char *sc; - register Char *dc; - - /* Initial DOT must be matched literally. */ - if (dp->d_name[0] == DOT && *pattern != DOT) - continue; - for (sc = (u_char *) dp->d_name, dc = pathend; - (*dc++ = *sc++) != EOS;) - continue; - if (!match(pathend, pattern, restpattern)) { - *pathend = EOS; - continue; - } - err = glob2(pathbuf, --dc, restpattern, pglob); - 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. - */ -static int -globextend(path, pglob) - const Char *path; - glob_t *pglob; -{ - register char **pathv; - register int i; - u_int newsize; - char *copy; - const Char *p; - - 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) - 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; - if ((copy = malloc(p - path)) != NULL) { - g_Ctoc(path, copy); - 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) - register Char *name, *pat, *patend; -{ - 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)) - 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 (c <= k && k <= pat[1]) - 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; -{ - register int i; - register 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); - } -} - -static DIR * -g_opendir(str, pglob) - register Char *str; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - if (!*str) - strcpy(buf, "."); - else - g_Ctoc(str, buf); - - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_opendir)(buf)); - - return(opendir(buf)); -} - -static int -g_lstat(fn, sb, pglob) - register Char *fn; - struct stat *sb; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - g_Ctoc(fn, buf); - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_lstat)(buf, sb)); - return(lstat(buf, sb)); -} - -static int -g_stat(fn, sb, pglob) - register Char *fn; - struct stat *sb; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - g_Ctoc(fn, buf); - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_stat)(buf, sb)); - return(stat(buf, sb)); -} - -static Char * -g_strchr(str, ch) - Char *str; - int ch; -{ - do { - if (*str == ch) - return (str); - } while (*str++); - return (NULL); -} - -#ifdef notdef -static Char * -g_strcat(dst, src) - Char *dst; - const Char* src; -{ - Char *sdst = dst; - - while (*dst++) - continue; - --dst; - while((*dst++ = *src++) != EOS) - continue; - - return (sdst); -} -#endif - -static void -g_Ctoc(str, buf) - register const Char *str; - char *buf; -{ - register char *dc; - - for (dc = buf; (*dc++ = *str++) != EOS;) - continue; -} - -#ifdef DEBUG -static void -qprintf(str, s) - const char *str; - register Char *s; -{ - register 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 diff --git a/gen/hton.c b/gen/hton.c deleted file mode 100644 index 4b765bb..0000000 --- a/gen/hton.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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 NeXT Computer, Inc. All rights reserved. - * - * File: hton.c - * Author: Matt Watson, NeXT Computer, Inc. - * - * Use the machine independent byte-swapping code for htonl-type functions. - * - * HISTORY - * 15-Dec-94 Matt Watson (Matt_Watson@NeXT.COM) - * Created. - */ - -#import - -long ntohl(long x) { - return NXSwapBigLongToHost(x); -} - -short ntohs(short x) { - return NXSwapBigShortToHost(x); -} - -long htonl(long x) { - return NXSwapHostLongToBig(x); -} - -short htons(short x) { - return NXSwapHostShortToBig(x); -} diff --git a/gen/intro.3 b/gen/intro.3 new file mode 100644 index 0000000..d5d0f64 --- /dev/null +++ b/gen/intro.3 @@ -0,0 +1,167 @@ +.\" 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. +.\" +.\" @(#)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 +.Dt INTRO 3 +.Os +.Sh NAME +.Nm intro +.Nd introduction to the C libraries +.Sh DESCRIPTION +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 , +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 +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 +for these functions. +There are several `libraries' or groups of functions included inside of +.Xr libc : +the standard +.Tn I/O +routines, +database routines, +bit operators, +string operators, +character tests and character operators, +des encryption routines, +storage allocation, time functions, signal handling and more. +.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 +.Xr termcap 3 . ) +.\" .It libvt0.a +.It Xr liby Pq Fl l Ns Ar y +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 +.El +.Sh SEE ALSO +.\" .Xr libc 3 , +.Xr cc 1 , +.Xr ld 1 , +.Xr nm 1 , +.Xr intro 2 , +.Xr math 3 , +.Xr stdio 3 +.\" .Sh LIST OF FUNCTIONS +.\" .Bl -column "strncasecmpxxx" "system" +.\" .Sy Name Description +.\" .El +.Sh HISTORY +An +.Nm +manual appeared in +.At v7 . diff --git a/gen/malloc.3 b/gen/malloc.3 new file mode 100644 index 0000000..53f193f --- /dev/null +++ b/gen/malloc.3 @@ -0,0 +1,253 @@ +.\" Copyright (c) 2002 Apple Computer, Inc. All rights reserved. +.\" +.\" @APPLE_LICENSE_HEADER_START@ +.\" +.\" The contents of this file constitute Original Code as defined in and +.\" are subject to the Apple Public Source License Version 1.1 (the +.\" "License"). You may not use this file except in compliance with the +.\" License. Please obtain a copy of the License at +.\" http://www.apple.com/publicsource and read it before using this file. +.\" +.\" This Original Code and all software distributed under the License are +.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the +.\" License for the specific language governing rights and limitations +.\" under the License. +.\" +.\" @APPLE_LICENSE_HEADER_END@ +.\" +.Dd November 21, 2002 +.Dt MALLOC 3 +.Os +.Sh NAME +.Nm malloc , calloc , valloc , realloc , free , malloc_size , malloc_good_size +.Nd memory allocation +.Sh SYNOPSIS +.In stdlib.h +.Ft void * +.Fn malloc "size_t size" +.Ft void * +.Fn calloc "size_t count" "size_t size" +.Ft void * +.Fn valloc "size_t size" +.Ft void * +.Fn realloc "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" +.Sh DESCRIPTION +The +.Fn malloc , +.Fn calloc , +.Fn valloc , +and +.Fn realloc +functions allocate memory. +The allocated memory is aligned such that it can be used for any data type, +including AltiVec-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 +function contiguously allocates enough space for +.Fa count +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 +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 +function tries to change the size of the allocation pointed to by +.Fa ptr +to +.Fa size , +and return +.Fa ptr . +If there is not enough room to enlarge the memory allocation pointed to by +.Fa ptr , +.Fn realloc +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. +.Fn realloc +returns a +.Dv NULL +pointer if there is an error, and the allocation pointed to by +.Fa ptr +is still valid. +.Pp +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 , +.Fn calloc , +and +.Fn valloc +functions return a pointer to allocated memory. +If there is an error, they return a +.Dv NULL +pointer and set +.Va errno +to +.Er ENOMEM . +.Pp +If successful, the +.Fn realloc +function returns a pointer to allocated memory. +If there is an error, it returns a +.Dv NULL +pointer and sets +.Va errno +to +.Er ENOMEM . +.Pp +The +.Fn free +function does not return a value. +.Sh DEBUGGING ALLOCATION ERRORS +A number of facilities are provided to aid in debugging allocation errors in +applications. +These facilities are primarily controlled via environment variables. +The recognized environment variables and their meanings are documented below. +.Sh ENVIRONMENT +The following environment variables change the behavior of the +allocation-related functions. +.Bl -tag -width ".Ev MallocStackLoggingNoCompact" +.It Ev MallocLogFile +Create/append messages to the given file path +.Fa +instead of writing to the standard error. +.It Ev MallocGuardEdges +If set, add a guard page before and after each large block. +.It Ev MallocDoNotProtectPrelude +If set, do not add a guard page before large blocks, +even if the +.Ev MallocGuardEdges +environment variable is set. +.It Ev MallocDoNotProtectPostlude +If set, do not add a guard page after large blocks, +even if the +.Ev MallocGuardEdges +environment variable is set. +.It Ev MallocStackLogging +If set, record all stacks, so that tools like +.Nm leaks +can be used. +.It Ev MallocStackLoggingNoCompact +If set, record all stacks in a manner that is compatible with the +.Nm malloc_history +program. +.It Ev MallocScribble +If set, fill memory that has been deallocated with 0x55 bytes. +This increases the likelihood that a program will fail due to accessing memory +that is no longer allocated. +.It Ev MallocCheckHeapStart +If set, specifies the number of allocations +.Fa +to wait before begining periodic heap checks every +.Fa +as specified by +.Ev MallocCheckHeapEach . +If +.Ev MallocCheckHeapStart +is set but +.Ev MallocCheckHeapEach +is not specified, the default check repetition is 1000. +.It Ev MallocCheckHeapEach +If set, run a consistency check on the heap every +.Fa +operations. +.Ev MallocCheckHeapEach +is only meaningful if +.Ev MallocCheckHeapStart +is also set. +.It Ev MallocCheckHeapSleep +Sets the number of seconds to sleep (waiting for a debugger to attach) when +.Ev MallocCheckHeapStart +is set and a heap corruption is detected. +The default is 100 seconds. +Setting this to zero means not to sleep at all. +Setting this to a negative number means to sleep (for the positive number of +seconds) only the very first time a heap corruption is detected. +.It Ev MallocCheckHeapAbort +When +.Ev MallocCheckHeapStart +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 +.Xr abort 3 +to be called if the pointer passed to +.Xr free 3 +was previously freed, or is otherwise illegal. +.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. +The list should correspond to this documentation. +.El +.Sh DIAGNOSTIC MESSAGES +.Sh SEE ALSO +.Xr leaks 1 , +.Xr malloc_history 1 , +.Xr abort 3 +.Pa /Developer/Documentation/ReleaseNotes/MallocOptions.html diff --git a/gen/malloc.c b/gen/malloc.c index 536aa8a..f5a9642 100644 --- a/gen/malloc.c +++ b/gen/malloc.c @@ -23,14 +23,15 @@ * @APPLE_LICENSE_HEADER_END@ */ -#define __POSIX_LIB__ +#include + #import #import #import #import #import -#import // for spin lock -#import +#import +#import #include #import "scalable_malloc.h" @@ -57,6 +58,13 @@ unsigned malloc_check_start = 0; // 0 means don't check unsigned malloc_check_counter = 0; unsigned malloc_check_each = 1000; +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 logfd = 2; // malloc_printf file descriptor + #define MALLOC_LOCK() LOCK(_malloc_lock) #define MALLOC_UNLOCK() UNLOCK(_malloc_lock) @@ -67,7 +75,8 @@ unsigned malloc_check_each = 1000; /********* Utilities ************/ -static inline malloc_zone_t *find_registered_zone(const void *ptr, size_t *returned_size) { +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 @@ -88,27 +97,41 @@ static inline malloc_zone_t *find_registered_zone(const void *ptr, size_t *retur /********* Creation and destruction ************/ -static void _malloc_initialize(void) { +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("Malloc: %d registered zones\n", malloc_num_zones); - // malloc_printf("malloc: malloc_zones is at 0x%x; malloc_num_zones is at 0x%x\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones); + // malloc_printf("malloc: malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones); } -static inline malloc_zone_t *inline_malloc_default_zone(void) { +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); return malloc_zones[0]; } -malloc_zone_t *malloc_default_zone(void) { +malloc_zone_t * +malloc_default_zone(void) { return inline_malloc_default_zone(); } -static void set_flags_from_environment(void) { +static void +set_flags_from_environment(void) { const char *flag; + flag = getenv("MallocLogFile"); + if (flag) { + int fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644); + if (fd >= 0) { + logfd = fd; + fcntl(fd, F_SETFD, 0); // clear close-on-exec flag + } else + malloc_printf("malloc[%d]: Could not open %s, using stderr\n", + getpid(), flag); + } if (getenv("MallocGuardEdges")) { malloc_debug_flags = SCALABLE_MALLOC_ADD_GUARD_PAGES; malloc_printf("malloc[%d]: protecting edges\n", getpid()); @@ -155,22 +178,51 @@ static void set_flags_from_environment(void) { if (malloc_check_each == -1) malloc_check_each = 1; } malloc_printf("malloc[%d]: checks heap after %dth operation and each %d operations\n", getpid(), malloc_check_start, malloc_check_each); + flag = getenv("MallocCheckHeapAbort"); + if (flag) + malloc_check_abort = strtol(flag, NULL, 0); + if (malloc_check_abort) + malloc_printf("malloc[%d]: will abort on heap corruption\n", + getpid()); + else { + flag = getenv("MallocCheckHeapSleep"); + if (flag) + malloc_check_sleep = strtol(flag, NULL, 0); + if (malloc_check_sleep > 0) + malloc_printf("malloc[%d]: will sleep for %d seconds on heap corruption\n", + getpid(), malloc_check_sleep); + else if (malloc_check_sleep < 0) + malloc_printf("malloc[%d]: will sleep once for %d seconds on heap corruption\n", + getpid(), -malloc_check_sleep); + else + malloc_printf("malloc[%d]: no sleep on heap corruption\n", + getpid()); + } } + flag = getenv("MallocBadFreeAbort"); + if (flag) + malloc_free_abort = strtol(flag, NULL, 0); if (getenv("MallocHelp")) { malloc_printf( "malloc[%d]: 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" "- MallocDoNotProtectPrelude to disable protection (when previous flag set)\n" "- MallocDoNotProtectPostlude to disable protection (when previous flag set)\n" "- MallocStackLogging to record all stacks. Tools like leaks can then be applied\n" "- MallocStackLoggingNoCompact to record all stacks. Needed for malloc_history\n" "- MallocScribble to detect writing on free blocks: 0x55 is written upon free\n" - "- MallocCheckHeapStart to check the heap from time to time after operations \n" + "- MallocCheckHeapStart to start checking the heap after operations\n" + "- 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" "- MallocHelp - this help!\n", getpid()); } } -malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags) { +malloc_zone_t * +malloc_create_zone(vm_size_t start_size, unsigned flags) { malloc_zone_t *zone; if (!malloc_num_zones) { char **env = * _NSGetEnviron(); @@ -190,14 +242,16 @@ malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags) { return zone; } -void malloc_destroy_zone(malloc_zone_t *zone) { +void +malloc_destroy_zone(malloc_zone_t *zone) { malloc_zone_unregister(zone); zone->destroy(zone); } /********* Block creation and manipulation ************/ -static void internal_check(void) { +static void +internal_check(void) { static vm_address_t *frames = NULL; static unsigned num_frames; if (malloc_zone_check(NULL)) { @@ -209,7 +263,7 @@ static void internal_check(void) { if (frames) { unsigned index = 1; malloc_printf("Stack for last operation where the malloc check succeeded: "); - while (index < num_frames) malloc_printf("0x%x ", frames[index++]); + while (index < num_frames) malloc_printf("%p ", frames[index++]); malloc_printf("\n(Use 'atos' for a symbolic stack)\n"); } if (malloc_check_each > 1) { @@ -217,17 +271,28 @@ static void internal_check(void) { unsigned recomm_start = (malloc_check_counter > malloc_check_each+1) ? malloc_check_counter-1-malloc_check_each : 1; malloc_printf("*** Recommend using 'setenv MallocCheckHeapStart %d; setenv MallocCheckHeapEach %d' to narrow down failure\n", recomm_start, recomm_each); } - malloc_printf("*** Sleeping for 100 seconds to leave time to attach\n"); - sleep(100); + if (malloc_check_abort) + abort(); + if (malloc_check_sleep > 0) { + malloc_printf("*** 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_check_sleep); + sleep(-malloc_check_sleep); + malloc_check_sleep = 0; + } } malloc_check_start += malloc_check_each; } -void *malloc_zone_malloc(malloc_zone_t *zone, size_t size) { +void * +malloc_zone_malloc(malloc_zone_t *zone, size_t size) { void *ptr; if ((unsigned)size >= MAX_ALLOCATION) { /* Probably a programming error */ - fprintf(stderr, "*** malloc_zone_malloc[%d]: argument too large: %d\n", getpid(), (unsigned)size); + malloc_printf("*** malloc_zone_malloc[%d]: argument too large: %d\n", getpid(), size); return NULL; } if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { @@ -238,14 +303,15 @@ void *malloc_zone_malloc(malloc_zone_t *zone, size_t size) { return ptr; } -void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { +void * +malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { void *ptr; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } if (((unsigned)num_items >= MAX_ALLOCATION) || ((unsigned)size >= MAX_ALLOCATION) || ((long long)size * num_items >= (long long) MAX_ALLOCATION)) { /* Probably a programming error */ - fprintf(stderr, "*** malloc_zone_calloc[%d]: arguments too large: %d,%d\n", getpid(), (unsigned)num_items, (unsigned)size); + malloc_printf("*** malloc_zone_calloc[%d]: arguments too large: %d,%d\n", getpid(), num_items, size); return NULL; } ptr = zone->calloc(zone, num_items, size); @@ -253,11 +319,12 @@ void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { return ptr; } -void *malloc_zone_valloc(malloc_zone_t *zone, size_t size) { +void * +malloc_zone_valloc(malloc_zone_t *zone, size_t size) { void *ptr; if ((unsigned)size >= MAX_ALLOCATION) { /* Probably a programming error */ - fprintf(stderr, "*** malloc_zone_valloc[%d]: argument too large: %d\n", getpid(), (unsigned)size); + malloc_printf("*** malloc_zone_valloc[%d]: argument too large: %d\n", getpid(), size); return NULL; } if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { @@ -268,7 +335,8 @@ void *malloc_zone_valloc(malloc_zone_t *zone, size_t size) { return ptr; } -void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { +void * +malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { void *new_ptr; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); @@ -278,7 +346,8 @@ void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { return new_ptr; } -void malloc_zone_free(malloc_zone_t *zone, void *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_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); @@ -286,7 +355,8 @@ void malloc_zone_free(malloc_zone_t *zone, void *ptr) { zone->free(zone, ptr); } -malloc_zone_t *malloc_zone_from_ptr(const void *ptr) { +malloc_zone_t * +malloc_zone_from_ptr(const void *ptr) { malloc_zone_t *zone; if (!ptr) return NULL; zone = find_registered_zone(ptr, NULL); @@ -295,7 +365,8 @@ malloc_zone_t *malloc_zone_from_ptr(const void *ptr) { /********* Functions for zone implementors ************/ -void malloc_zone_register(malloc_zone_t *zone) { +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) { @@ -315,7 +386,8 @@ void malloc_zone_register(malloc_zone_t *zone) { // malloc_printf("Registered %p malloc_zones at address %p is %p [%d zones]\n", zone, &malloc_zones, malloc_zones, malloc_num_zones); } -void malloc_zone_unregister(malloc_zone_t *z) { +void +malloc_zone_unregister(malloc_zone_t *z) { unsigned index; MALLOC_LOCK(); index = malloc_num_zones; @@ -328,10 +400,11 @@ void malloc_zone_unregister(malloc_zone_t *z) { } } MALLOC_UNLOCK(); - fprintf(stderr, "*** malloc[%d]: malloc_zone_unregister() failed for %p\n", getpid(), z); + malloc_printf("*** malloc[%d]: malloc_zone_unregister() failed for %p\n", getpid(), z); } -void malloc_set_zone_name(malloc_zone_t *z, const char *name) { +void +malloc_set_zone_name(malloc_zone_t *z, const char *name) { char *newName; if (z->zone_name) { free((char *)z->zone_name); @@ -342,11 +415,13 @@ void malloc_set_zone_name(malloc_zone_t *z, const char *name) { z->zone_name = (const char *)newName; } -const char *malloc_get_zone_name(malloc_zone_t *zone) { +const char * +malloc_get_zone_name(malloc_zone_t *zone) { return zone->zone_name; } -static char *_malloc_append_unsigned(unsigned value, unsigned base, char *head) { +static char * +_malloc_append_unsigned(unsigned value, unsigned base, char *head) { if (!value) { head[0] = '0'; } else { @@ -357,7 +432,8 @@ static char *_malloc_append_unsigned(unsigned value, unsigned base, char *head) return head+1; } -void malloc_printf(const char *format, ...) { +void +malloc_printf(const char *format, ...) { va_list args; char buf[1024]; char *head = buf; @@ -368,15 +444,31 @@ void malloc_printf(const char *format, ...) { head = _malloc_append_unsigned(((unsigned)&args) >> 12, 16, head); *head++ = ' '; #endif - nums = args; + nums = (void *)args; while (ch = *format++) { if (ch == '%') { ch = *format++; if (ch == 's') { char *str = (char *)(*nums++); - write(2, buf, head - buf); + write(logfd, buf, head - buf); head = buf; - write(2, str, strlen(str)); + write(logfd, str, strlen(str)); + } else if (ch == 'y') { + unsigned num = *nums++; + if (num == 0) { + *head++ = '0'; + } else if (num >= 10 * 1024 *1024) { + // use a round number of MB + head = _malloc_append_unsigned(num >> 20, 10, head); + *head++ = 'M'; *head++ = 'B'; + } else if (num >= 10 * 1024) { + // use a round amount of KB + head = _malloc_append_unsigned(num >> 10, 10, head); + *head++ = 'K'; *head++ = 'B'; + } else { + head = _malloc_append_unsigned(num, 10, head); + *head++ = 'b'; + } } else { if (ch == 'p') { *head++ = '0'; *head++ = 'x'; @@ -387,70 +479,149 @@ void malloc_printf(const char *format, ...) { *head++ = ch; } } - write(2, buf, head - buf); fflush(stderr); + write(logfd, buf, head - buf); fflush(stderr); va_end(args); } /********* Generic ANSI callouts ************/ -void *malloc(size_t size) { - return malloc_zone_malloc(inline_malloc_default_zone(), size); +void * +malloc(size_t size) { + void *retval; + retval = malloc_zone_malloc(inline_malloc_default_zone(), size); + if (retval == NULL) { + errno = ENOMEM; + } + return retval; } -void *calloc(size_t num_items, size_t size) { - return malloc_zone_calloc(inline_malloc_default_zone(), num_items, size); +void * +calloc(size_t num_items, size_t size) { + void *retval; + retval = malloc_zone_calloc(inline_malloc_default_zone(), num_items, size); + if (retval == NULL) { + errno = ENOMEM; + } + return retval; } -void free(void *ptr) { +void +free(void *ptr) { malloc_zone_t *zone; if (!ptr) return; zone = find_registered_zone(ptr, NULL); if (zone) { malloc_zone_free(zone, ptr); } else { - fprintf(stderr, "*** malloc[%d]: 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", getpid(), ptr); + malloc_printf("*** malloc[%d]: 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", getpid(), ptr); + if (malloc_free_abort) + abort(); } } -void *realloc(void *old_ptr, size_t new_size) { +void * +realloc(void *old_ptr, size_t new_size) { + void *retval; malloc_zone_t *zone; size_t old_size = 0; - if (!old_ptr) return malloc_zone_malloc(inline_malloc_default_zone(), new_size); - zone = find_registered_zone(old_ptr, &old_size); - if (zone && (old_size >= new_size)) return old_ptr; - if (!zone) zone = inline_malloc_default_zone(); - return malloc_zone_realloc(zone, old_ptr, new_size); + 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(); + retval = malloc_zone_realloc(zone, old_ptr, new_size); + } + if (retval == NULL) { + errno = ENOMEM; + } + return retval; } -void *valloc(size_t size) { +void * +valloc(size_t size) { + void *retval; malloc_zone_t *zone = inline_malloc_default_zone(); - return malloc_zone_valloc(zone, size); + retval = malloc_zone_valloc(zone, size); + if (retval == NULL) { + errno = ENOMEM; + } + return retval; } -extern void vfree(void *ptr) { +extern void +vfree(void *ptr) { free(ptr); } -size_t malloc_size(const void *ptr) { +size_t +malloc_size(const void *ptr) { size_t size = 0; if (!ptr) return size; (void)find_registered_zone(ptr, &size); return size; } -size_t malloc_good_size (size_t size) { +size_t +malloc_good_size (size_t size) { malloc_zone_t *zone = inline_malloc_default_zone(); return zone->introspect->good_size(zone, size); } +/********* Batch methods ************/ + +unsigned +malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested) { + unsigned (*batch_malloc)(malloc_zone_t *, size_t, void **, unsigned) = zone-> batch_malloc; + if (! batch_malloc) return 0; + if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { + internal_check(); + } + unsigned batched = batch_malloc(zone, size, results, num_requested); + 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); + index++; + } + } + return batched; +} + +void +malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) { + if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { + internal_check(); + } + 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); + index++; + } + } + void (*batch_free)(malloc_zone_t *, void **, unsigned) = zone-> batch_free; + if (batch_free) { + batch_free(zone, to_be_freed, num); + } else { + void (*free_fun)(malloc_zone_t *, void *) = zone->free; + while (num--) { + void *ptr = *to_be_freed++; + free_fun(zone, ptr); + } + } +} + /********* Functions for performance tools ************/ -static kern_return_t _malloc_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { +static kern_return_t +_malloc_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { *ptr = (void *)address; return 0; } -kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count) { +kern_return_t +malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count) { // Note that the 2 following addresses are not correct if the address of the target is different from your own. This notably occurs if the address of System.framework is slid (e.g. different than at B & I ) vm_address_t remote_malloc_zones = (vm_address_t)&malloc_zones; vm_address_t remote_malloc_num_zones = (vm_address_t)&malloc_num_zones; @@ -462,25 +633,25 @@ kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_addre if (!reader) reader = _malloc_default_reader; // printf("Read malloc_zones at address %p should be %p\n", &malloc_zones, malloc_zones); err = reader(task, remote_malloc_zones, sizeof(void *), (void **)&zones_address_ref); - // printf("Read malloc_zones[0x%x]=%p\n", remote_malloc_zones, *zones_address_ref); + // printf("Read malloc_zones[%p]=%p\n", remote_malloc_zones, *zones_address_ref); if (err) { - fprintf(stderr, "*** malloc[%d]: malloc_get_all_zones: error reading zones_address at 0x%x\n", getpid(), (unsigned)remote_malloc_zones); + malloc_printf("*** malloc[%d]: malloc_get_all_zones: error reading zones_address at %p\n", getpid(), (unsigned)remote_malloc_zones); return err; } zones_address = *zones_address_ref; // printf("Reading num_zones at address %p\n", remote_malloc_num_zones); err = reader(task, remote_malloc_num_zones, sizeof(unsigned), (void **)&num_zones_ref); if (err) { - fprintf(stderr, "*** malloc[%d]: malloc_get_all_zones: error reading num_zones at 0x%x\n", getpid(), (unsigned)remote_malloc_num_zones); + malloc_printf("*** malloc[%d]: malloc_get_all_zones: error reading num_zones at %p\n", getpid(), (unsigned)remote_malloc_num_zones); return err; } num_zones = *num_zones_ref; - // printf("Read malloc_num_zones[0x%x]=%d\n", remote_malloc_num_zones, num_zones); + // printf("Read malloc_num_zones[%p]=%d\n", remote_malloc_num_zones, num_zones); *count = num_zones; // printf("malloc_get_all_zones succesfully found %d zones\n", num_zones); err = reader(task, zones_address, sizeof(malloc_zone_t *) * num_zones, (void **)addresses); if (err) { - fprintf(stderr, "*** malloc[%d]: malloc_get_all_zones: error reading zones at 0x%x\n", getpid(), (unsigned)&zones_address); + malloc_printf("*** malloc[%d]: malloc_get_all_zones: error reading zones at %p\n", getpid(), (unsigned)&zones_address); return err; } // printf("malloc_get_all_zones succesfully read %d zones\n", num_zones); @@ -489,7 +660,8 @@ kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_addre /********* Debug helpers ************/ -void malloc_zone_print_ptr_info(void *ptr) { +void +malloc_zone_print_ptr_info(void *ptr) { malloc_zone_t *zone; if (!ptr) return; zone = find_registered_zone(ptr, NULL); @@ -500,7 +672,8 @@ void malloc_zone_print_ptr_info(void *ptr) { } } -boolean_t malloc_zone_check(malloc_zone_t *zone) { +boolean_t +malloc_zone_check(malloc_zone_t *zone) { boolean_t ok = 1; if (!zone) { unsigned index = 0; @@ -514,7 +687,8 @@ boolean_t malloc_zone_check(malloc_zone_t *zone) { return ok; } -void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { +void +malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { if (!zone) { unsigned index = 0; while (index < malloc_num_zones) { @@ -526,7 +700,27 @@ void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { } } -void malloc_zone_log(malloc_zone_t *zone, void *address) { +void +malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) { + if (!zone) { + memset(stats, 0, sizeof(stats)); + unsigned index = 0; + while (index < malloc_num_zones) { + zone = malloc_zones[index++]; + malloc_statistics_t this_stats; + zone->introspect->statistics(zone, &this_stats); + stats->blocks_in_use += this_stats.blocks_in_use; + stats->size_in_use += this_stats.size_in_use; + stats->max_size_in_use += this_stats.max_size_in_use; + stats->size_allocated += this_stats.size_allocated; + } + } else { + zone->introspect->statistics(zone, stats); + } +} + +void +malloc_zone_log(malloc_zone_t *zone, void *address) { if (!zone) { unsigned index = 0; while (index < malloc_num_zones) { @@ -540,8 +734,9 @@ void malloc_zone_log(malloc_zone_t *zone, void *address) { /********* Misc other entry points ************/ -static void DefaultMallocError(int x) { - fprintf(stderr, "*** malloc[%d]: error %d\n", getpid(), x); +static void +DefaultMallocError(int x) { + malloc_printf("*** malloc[%d]: error %d\n", getpid(), x); #if USE_SLEEP_RATHER_THAN_ABORT sleep(3600); #else @@ -549,11 +744,13 @@ static void DefaultMallocError(int x) { #endif } -void (*malloc_error(void (*func)(int)))(int) { +void (* +malloc_error(void (*func)(int)))(int) { return DefaultMallocError; } -void _malloc_fork_prepare() { +void +_malloc_fork_prepare() { /* Prepare the malloc module for a fork by insuring that no thread is in a malloc critical section */ unsigned index = 0; MALLOC_LOCK(); @@ -563,7 +760,8 @@ void _malloc_fork_prepare() { } } -void _malloc_fork_parent() { +void +_malloc_fork_parent() { /* Called in the parent process after a fork() to resume normal operation. */ unsigned index = 0; MALLOC_UNLOCK(); @@ -573,7 +771,8 @@ void _malloc_fork_parent() { } } -void _malloc_fork_child() { +void +_malloc_fork_child() { /* Called in the child process after a fork() to resume normal operation. In the MTASK case we also have to change memory inheritance so that the child does not share memory with the parent. */ unsigned index = 0; MALLOC_UNLOCK(); @@ -583,7 +782,8 @@ void _malloc_fork_child() { } } -size_t mstats(void) { +size_t +mstats(void) { malloc_zone_print(NULL, 0); return 1; } @@ -596,25 +796,28 @@ size_t mstats(void) { #warning PHASE OUT THE FOLLOWING FUNCTIONS #endif -void set_malloc_singlethreaded(boolean_t single) { +void +set_malloc_singlethreaded(boolean_t single) { static boolean_t warned = 0; if (!warned) { #if PHASE_OUT_OLD_MALLOC - fprintf(stderr, "*** malloc[%d]: OBSOLETE: set_malloc_singlethreaded(%d)\n", getpid(), single); + malloc_printf("*** malloc[%d]: OBSOLETE: set_malloc_singlethreaded(%d)\n", getpid(), single); #endif warned = 1; } } -void malloc_singlethreaded() { +void +malloc_singlethreaded() { static boolean_t warned = 0; if (!warned) { - fprintf(stderr, "*** malloc[%d]: OBSOLETE: malloc_singlethreaded()\n", getpid()); + malloc_printf("*** malloc[%d]: OBSOLETE: malloc_singlethreaded()\n", getpid()); warned = 1; } } -int malloc_debug(int level) { - fprintf(stderr, "*** malloc[%d]: OBSOLETE: malloc_debug()\n", getpid()); +int +malloc_debug(int level) { + malloc_printf("*** malloc[%d]: OBSOLETE: malloc_debug()\n", getpid()); return 0; } diff --git a/gen/msgctl.3 b/gen/msgctl.3 deleted file mode 100644 index 83af0c3..0000000 --- a/gen/msgctl.3 +++ /dev/null @@ -1,206 +0,0 @@ -.\" $NetBSD: msgctl.2,v 1.1 1995/10/16 23:49:15 jtc Exp $ -.\" -.\" Copyright (c) 1995 Frank van der Linden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided 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 -.\" by Frank van der Linden -.\" 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/msgctl.3,v 1.16 2001/10/01 16:08:51 ru Exp $ -.\"/ -.Dd November 24, 1997 -.Dt MSGCTL 3 -.Os -.Sh NAME -.Nm msgctl -.Nd message control operations -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/ipc.h -.In sys/msg.h -.Ft int -.Fn msgctl "int msqid" "int cmd" "struct msqid_ds *buf" -.Sh DESCRIPTION -The -.Fn msgctl -system call performs some control operations on the message queue specified -by -.Fa msqid . -.Pp -Each message queue has a data structure associated with it, parts of which -may be altered by -.Fn msgctl -and parts of which determine the actions of -.Fn msgctl . -The data structure is defined in -.Aq Pa sys/msg.h -and contains (amongst others) the following members: -.Bd -literal -struct msqid_ds { - struct ipc_perm msg_perm; /* msg queue permission bits */ - struct msg *msg_first; /* first message in the queue */ - struct msg *msg_last; /* last message in the queue */ - u_long msg_cbytes; /* number of bytes in use on the queue */ - u_long msg_qnum; /* number of msgs in the queue */ - u_long msg_qbytes; /* max # of bytes on the queue */ - pid_t msg_lspid; /* pid of last msgsnd() */ - pid_t msg_lrpid; /* pid of last msgrcv() */ - time_t msg_stime; /* time of last msgsnd() */ - long msg_pad1; - time_t msg_rtime; /* time of last msgrcv() */ - long msg_pad2; - time_t msg_ctime; /* time of last msgctl() */ - long msg_pad3; - long msg_pad4[4]; -}; -.Ed -.Pp -The -.Vt ipc_perm -structure used inside the -.Vt shmid_ds -structure is defined in -.Aq Pa sys/ipc.h -and looks like this: -.Bd -literal -struct ipc_perm { - ushort cuid; /* creator user id */ - ushort cgid; /* creator group id */ - ushort uid; /* user id */ - ushort gid; /* group id */ - ushort mode; /* r/w permission */ - ushort seq; /* sequence # (to generate unique msg/sem/shm id) */ - key_t key; /* user specified msg/sem/shm key */ -}; -.Ed -.Pp -The operation to be performed by -.Fn msgctl -is specified in -.Fa cmd -and is one of: -.Bl -tag -width IPC_RMIDX -.It Dv IPC_STAT -Gather information about the message queue and place it in the -structure pointed to by -.Fa buf . -.It Dv IPC_SET -Set the value of the -.Va msg_perm.uid , -.Va msg_perm.gid , -.Va msg_perm.mode -and -.Va msg_qbytes -fields in the structure associated with -.Fa msqid . -The values are taken from the corresponding fields in the structure -pointed to by -.Fa buf . -This operation can only be executed by the super-user, or a process that -has an effective user id equal to either -.Va msg_perm.cuid -or -.Va msg_perm.uid -in the data structure associated with the message queue. -The value of -.Va msg_qbytes -can only be increased by the super-user. -Values for -.Va msg_qbytes -that exceed the system limit (MSGMNB from -.Aq Pa sys/msg.h ) -are silently truncated to that limit. -.It Dv IPC_RMID -Remove the message queue specified by -.Fa msqid -and destroy the data associated with it. -Only the super-user or a process -with an effective uid equal to the -.Va msg_perm.cuid -or -.Va msg_perm.uid -values in the data structure associated with the queue can do this. -.El -.Pp -The permission to read from or write to a message queue (see -.Xr msgsnd 3 -and -.Xr msgrcv 3 ) -is determined by the -.Va msg_perm.mode -field in the same way as is -done with files (see -.Xr chmod 2 ) , -but the effective uid can match either the -.Va msg_perm.cuid -field or the -.Va msg_perm.uid -field, and the -effective gid can match either -.Va msg_perm.cgid -or -.Va msg_perm.gid . -.Sh RETURN VALUES -.Rv -std msgctl -.Sh ERRORS -.Fn msgctl -will fail if: -.Bl -tag -width Er -.It Bq Er EPERM -.Fa cmd -is equal to IPC_SET or IPC_RMID and the caller is not the super-user, nor does -the effective uid match either the -.Va msg_perm.uid -or -.Va msg_perm.cuid -fields of the data structure associated with the message queue. -.Pp -An attempt is made to increase the value of -.Va msg_qbytes -through IPC_SET -but the caller is not the super-user. -.It Bq Er EACCES -The command is IPC_STAT -and the caller has no read permission for this message queue. -.It Bq Er EINVAL -.Fa msqid -is not a valid message queue identifier. -.Pp -.Va cmd -is not a valid command. -.It Bq Er EFAULT -.Fa buf -specifies an invalid address. -.El -.Sh SEE ALSO -.Xr msgget 3 , -.Xr msgrcv 3 , -.Xr msgsnd 3 -.Sh HISTORY -Message queues appeared in the first release of -.At V . diff --git a/gen/msgget.3 b/gen/msgget.3 deleted file mode 100644 index 6a7ee9e..0000000 --- a/gen/msgget.3 +++ /dev/null @@ -1,139 +0,0 @@ -.\" $NetBSD: msgget.2,v 1.1 1995/10/16 23:49:19 jtc Exp $ -.\" -.\" Copyright (c) 1995 Frank van der Linden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided 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 -.\" by Frank van der Linden -.\" 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/msgget.3,v 1.12 2001/10/01 16:08:51 ru Exp $ -.\" -.\"/ -.Dd August 17, 1995 -.Dt MSGGET 3 -.Os -.Sh NAME -.Nm msgget -.Nd get message queue -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/ipc.h -.In sys/msg.h -.Ft int -.Fn msgget "key_t key" "int msgflg" -.Sh DESCRIPTION -.Fn msgget -returns the message queue identifier associated with -.Fa key . -A message queue identifier is a unique integer greater than zero. -.Pp -A message queue is created if either -.Fa key -is equal to -.Dv IPC_PRIVATE , -or -.Fa key -does not have a message queue identifier associated with it, and the -.Dv IPC_CREAT -bit is set in -.Fa msgflg . -.Pp -If a new message queue is created, the data structure associated with it (the -.Va msqid_ds -structure, see -.Xr msgctl 3 ) -is initialized as follows: -.Bl -bullet -.It -.Va msg_perm.cuid -and -.Va msg_perm.uid -are set to the effective uid of the calling process. -.It -.Va msg_perm.gid -and -.Va msg_perm.cgid -are set to the effective gid of the calling process. -.It -.Va msg_perm.mode -is set to the lower 9 bits of -.Fa msgflg . -.It -.Va msg_cbytes , -.Va msg_qnum , -.Va msg_lspid , -.Va msg_lrpid , -.Va msg_rtime , -and -.Va msg_stime -are set to 0. -.It -.Va msg_qbytes -is set to the system wide maximum value for the number of bytes in a queue -.Pf ( Dv MSGMNB ) . -.It -.Va msg_ctime -is set to the current time. -.El -.Sh RETURN VALUES -Upon successful completion a positive message queue identifier is returned. -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 EACCES -A message queue is already associated with -.Fa key -and the caller has no permission to access it. -.It Bq Er EEXIST -Both -.Dv IPC_CREAT -and -.Dv IPC_EXCL -are set in -.Fa msgflg , -and a message queue is already associated with -.Fa key . -.It Bq Er ENOSPC -A new message queue could not be created because the system limit for -the number of message queues has been reached. -.It Bq Er ENOENT -.Dv IPC_CREAT -was not set in -.Fa msgflg -and no message queue associated with -.Fa key -was found. -.El -.Sh SEE ALSO -.Xr msgctl 3 , -.Xr msgrcv 3 , -.Xr msgsnd 3 -.Sh HISTORY -Message queues appeared in the first release of -.At V . diff --git a/gen/msgrcv.3 b/gen/msgrcv.3 deleted file mode 100644 index b80f987..0000000 --- a/gen/msgrcv.3 +++ /dev/null @@ -1,202 +0,0 @@ -.\" $NetBSD: msgrcv.2,v 1.1 1995/10/16 23:49:20 jtc Exp $ -.\" -.\" Copyright (c) 1995 Frank van der Linden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided 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 -.\" by Frank van der Linden -.\" 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/msgrcv.3,v 1.16 2001/10/01 16:08:51 ru Exp $ -.\" -.\"/ -.Dd November 24, 1997 -.Dt MSGRCV 3 -.Os -.Sh NAME -.Nm msgrcv -.Nd receive a message from a message queue -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/ipc.h -.In sys/msg.h -.Ft int -.Fn msgrcv "int msqid" "void *msgp" "size_t msgsz" "long msgtyp" "int msgflg" -.Sh DESCRIPTION -The -.Fn msgrcv -function receives a message from the message queue specified in -.Fa msqid , -and places it into the structure pointed to by -.Fa msgp . -This structure should consist of the following members: -.Bd -literal - long mtype; /* message type */ - char mtext[1]; /* body of message */ -.Ed -.Pp -.Va mtype -is an integer greater than 0 that can be used for selecting messages, -.Va mtext -is an array of bytes, with a size up to that of the system limit -.Pf ( Dv MSGMAX ) . -.Pp -The value of -.Fa msgtyp -has one of the following meanings: -.Bl -bullet -.It -.Fa msgtyp -is greater than 0. The first message of type -.Fa msgtyp -will be received. -.It -.Fa msgtyp -is equal to 0. The first message on the queue will be received. -.It -.Fa msgtyp -is less than 0. The first message of the lowest message type that is -less than or equal to the absolute value of -.Fa msgtyp -will be received. -.El -.Pp -.Fa msgsz -specifies the maximum length of the requested message. -If the received -message has a length greater than -.Fa msgsz -it will be silently truncated if the -.Dv MSG_NOERROR -flag is set in -.Fa msgflg , -otherwise an error will be returned. -.Pp -If no matching message is present on the message queue specified by -.Fa msqid , -the behavior of -.Fn msgrcv -depends on whether the -.Dv IPC_NOWAIT -flag is set in -.Fa msgflg -or not. -If -.Dv IPC_NOWAIT -is set, -.Fn msgrcv -will immediately return a value of -1, and set -.Va errno -to -.Er EAGAIN . -If -.Dv IPC_NOWAIT -is not set, the calling process will be blocked -until: -.Bl -bullet -.It -A message of the requested type becomes available on the message queue. -.It -The message queue is removed, in which case -1 will be returned, and -.Va errno -set to -.Er EINVAL . -.It -A signal is received and caught. -1 is returned, and -.Va errno -set to -.Er EINTR . -.El -.Pp -If a message is successfully received, the data structure associated with -.Fa msqid -is updated as follows: -.Bl -bullet -.It -.Va msg_cbytes -is decremented by the size of the message. -.It -.Va msg_lrpid -is set to the pid of the caller. -.It -.Va msg_lrtime -is set to the current time. -.It -.Va msg_qnum -is decremented by 1. -.El -.Sh RETURN VALUES -Upon successful completion, -.Fn msgrcv -returns the number of bytes received into the -.Va mtext -field of the structure pointed to by -.Fa msgp . -Otherwise, -1 is returned, and -.Va errno -set to indicate the error. -.Sh ERRORS -.Fn msgrcv -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa msqid -is not a valid message queue identifier. -.Pp -The message queue was removed while -.Fn msgrcv -was waiting for a message of the requested type to become available on it. -.Pp -.Fa msgsz -is less than 0. -.It Bq Er E2BIG -A matching message was received, but its size was greater than -.Fa msgsz -and the -.Dv MSG_NOERROR -flag was not set in -.Fa msgflg . -.It Bq Er EACCES -The calling process does not have read access to the message queue. -.It Bq Er EFAULT -.Fa msgp -points to an invalid address. -.It Bq Er EINTR -The system call was interrupted by the delivery of a signal. -.It Bq Er EAGAIN -There is no message of the requested type available on the message queue, -and -.Dv IPC_NOWAIT -is set in -.Fa msgflg . -.El -.Sh SEE ALSO -.Xr msgctl 3 , -.Xr msgget 3 , -.Xr msgsnd 3 -.Sh HISTORY -Message queues appeared in the first release of -.At V . diff --git a/gen/msgsnd.3 b/gen/msgsnd.3 deleted file mode 100644 index ee70922..0000000 --- a/gen/msgsnd.3 +++ /dev/null @@ -1,167 +0,0 @@ -.\" $NetBSD: msgsnd.2,v 1.1 1995/10/16 23:49:24 jtc Exp $ -.\" -.\" Copyright (c) 1995 Frank van der Linden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided 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 -.\" by Frank van der Linden -.\" 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/msgsnd.3,v 1.16 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd November 24, 1997 -.Dt MSGSND 3 -.Os -.Sh NAME -.Nm msgsnd -.Nd send a message to a message queue -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/ipc.h -.In sys/msg.h -.Ft int -.Fn msgsnd "int msqid" "void *msgp" "size_t msgsz" "int msgflg" -.Sh DESCRIPTION -The -.Fn msgsnd -function sends a message to the message queue specified in -.Fa msqid . -.Fa msgp -points to a structure containing the message. -This structure should -consist of the following members: -.Bd -literal - long mtype; /* message type */ - char mtext[1]; /* body of message */ -.Ed -.Pp -.Va mtype -is an integer greater than 0 that can be used for selecting messages (see -.Xr msgrcv 3 ) , -.Va mtext -is an array of bytes, with a size up to that of the system limit -.Pf ( Dv MSGMAX ) . -.Pp -If the number of bytes already on the message queue plus -.Fa msgsz -is bigger than the maximum number of bytes on the message queue -.Pf ( Va msg_qbytes , -see -.Xr msgctl 3 ) , -or the number of messages on all queues system-wide is already equal to -the system limit, -.Fa msgflg -determines the action of -.Fn msgsnd . -If -.Fa msgflg -has -.Dv IPC_NOWAIT -mask set in it, the call will return immediately. -If -.Fa msgflg -does not have -.Dv IPC_NOWAIT -set in it, the call will block until: -.Bl -bullet -.It -The condition which caused the call to block does no longer exist. -The message will be sent. -.It -The message queue is removed, in which case -1 will be returned, and -.Va errno -is set to -.Er EINVAL . -.It -The caller catches a signal. -The call returns with -.Va errno -set to -.Er EINTR . -.El -.Pp -After a successful call, the data structure associated with the message -queue is updated in the following way: -.Bl -bullet -.It -.Va msg_cbytes -is incremented by the size of the message. -.It -.Va msg_qnum -is incremented by 1. -.It -.Va msg_lspid -is set to the pid of the calling process. -.It -.Va msg_stime -is set to the current time. -.El -.Sh RETURN VALUES -.Rv -std msgsnd -.Sh ERRORS -.Fn msgsnd -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa msqid -is not a valid message queue identifier -.Pp -The message queue was removed while -.Fn msgsnd -was waiting for a resource to become available in order to deliver the -message. -.Pp -.Fa msgsz -is less than 0, or greater than -.Va msg_qbytes . -.Pp -.Fa mtype -is not greater than 0. -.It Bq Er EACCES -The calling process does not have write access to the message queue. -.It Bq Er EAGAIN -There was no space for this message either on the queue, or in the whole -system, and -.Dv IPC_NOWAIT -was set in -.Fa msgflg . -.It Bq Er EFAULT -.Fa msgp -points to an invalid address. -.It Bq Er EINTR -The system call was interrupted by the delivery of a signal. -.El -.Sh BUGS -.Nx -and -.Fx -do not define the -.Er EIDRM -error value, which should be used -in the case of a removed message queue. -.Sh HISTORY -Message queues appeared in the first release of AT&T Unix System V. diff --git a/gen/nlist.c b/gen/nlist.c index 41ab4ec..bc09f42 100644 --- a/gen/nlist.c +++ b/gen/nlist.c @@ -101,6 +101,8 @@ unsigned long a_drsize; /* size of data relocation */ */ #define CPUSUBTYPE_SUPPORT 0 +int __fdnlist(int fd, struct nlist *list); + /* * nlist - retreive attributes from name list (string table version) */ @@ -129,7 +131,7 @@ __fdnlist(fd, list) { register struct nlist *p, *q; register char *s1, *s2; - register n, m; + register int n, m; int maxlen, nreq; off_t sa; /* symbol address */ off_t ss; /* start of strings */ @@ -212,7 +214,7 @@ __fdnlist(fd, list) #if CPUSUBTYPE_SUPPORT fap = cpusubtype_getbestarch(hbi.cpu_type, hbi.cpu_subtype, fat_archs, fh.nfat_arch); -#else CPUSUBTYPE_SUPPORT +#else #warning Use the cpusubtype functions!!! fap = NULL; for (i = 0; i < fh.nfat_arch; i++) { @@ -221,7 +223,7 @@ __fdnlist(fd, list) break; } } -#endif CPUSUBTYPE_SUPPORT +#endif /* CPUSUBTYPE_SUPPORT */ if (!fap) { free(fat_archs); return (-1); diff --git a/gen/psignal.c b/gen/psignal.c deleted file mode 100644 index d7857cd..0000000 --- a/gen/psignal.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -/* - * Print the name of the signal indicated - * along with the supplied message. - */ -#include -#include -#include - -extern const char *const sys_siglist[]; - -void -psignal(sig, s) - unsigned int sig; - const char *s; -{ - register const char *c; - register int n; - - if (sig < NSIG) - c = (char *)sys_siglist[sig]; - else - c = "Unknown signal"; - n = strlen(s); - if (n) { - (void)write(STDERR_FILENO, s, n); - (void)write(STDERR_FILENO, ": ", 2); - } - (void)write(STDERR_FILENO, c, strlen(c)); - (void)write(STDERR_FILENO, "\n", 1); -} diff --git a/gen/pwcache.3 b/gen/pwcache.3 index 42f2592..8a3d3ea 100644 --- a/gen/pwcache.3 +++ b/gen/pwcache.3 @@ -41,11 +41,12 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In stdlib.h +.In pwd.h .Ft char * -.Fn user_from_uid "unsigned long uid" "int nouser" +.Fn user_from_uid "uid_t uid" "int nouser" +.In grp.h .Ft char * -.Fn group_from_gid "unsigned long gid" "int nogroup" +.Fn group_from_gid "gid_t gid" "int nogroup" .Sh DESCRIPTION The .Fn user_from_uid diff --git a/gen/pwcache.c b/gen/pwcache.c deleted file mode 100644 index bb5cf40..0000000 --- a/gen/pwcache.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include - -#include -#include -#include -#include - -#define NCACHE 64 /* power of 2 */ -#define MASK NCACHE - 1 /* bits to store with */ - -#ifdef NeXT -/* lookupd caches users, so there's no point in another cache here */ -char * -user_from_uid(uid, nouser) - uid_t uid; - int nouser; -{ - static struct passwd *pw; - - if ((pw = getpwuid(uid)) == NULL) return (NULL); - return pw->pw_name; -} -#else -char * -user_from_uid(uid, nouser) - uid_t uid; - int nouser; -{ - static struct ncache { - uid_t uid; - char name[UT_NAMESIZE + 1]; - } c_uid[NCACHE]; - static int pwopen; - static char nbuf[15]; /* 32 bits == 10 digits */ - register struct passwd *pw; - register struct ncache *cp; - - cp = c_uid + (uid & MASK); - if (cp->uid != uid || !*cp->name) { - if (pwopen == 0) { - setpassent(1); - pwopen = 1; - } - if ((pw = getpwuid(uid)) == NULL) { - if (nouser) - return (NULL); - (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); - return (nbuf); - } - cp->uid = uid; - (void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE); - cp->name[UT_NAMESIZE] = '\0'; - } - return (cp->name); -} -#endif - -#ifdef NeXT -/* lookupd caches groups, so there's no point in another cache here */ -char * -group_from_gid(gid, nogroup) - gid_t gid; - int nogroup; -{ - static struct group *gr; - - if ((gr = getgrgid(gid)) == NULL) return (NULL); - return gr->gr_name; -} -#else -char * -group_from_gid(gid, nogroup) - gid_t gid; - int nogroup; -{ - static struct ncache { - gid_t gid; - char name[UT_NAMESIZE + 1]; - } c_gid[NCACHE]; - static int gropen; - static char nbuf[15]; /* 32 bits == 10 digits */ - struct group *gr; - struct ncache *cp; - - cp = c_gid + (gid & MASK); - if (cp->gid != gid || !*cp->name) { - if (gropen == 0) { - setgroupent(1); - gropen = 1; - } - if ((gr = getgrgid(gid)) == NULL) { - if (nogroup) - return (NULL); - (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); - return (nbuf); - } - cp->gid = gid; - (void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE); - cp->name[UT_NAMESIZE] = '\0'; - } - return (cp->name); -} -#endif NeXT diff --git a/gen/rcmd.c b/gen/rcmd.c deleted file mode 100644 index bc1d06d..0000000 --- a/gen/rcmd.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 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[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int __ivaliduser __P((FILE *, u_long, const char *, const char *)); -static int __icheckhost __P((u_long, char *)); - -int -rcmd(ahost, rport, locuser, remuser, cmd, fd2p) - char **ahost; - u_short rport; - const char *locuser, *remuser, *cmd; - int *fd2p; -{ - struct hostent *hp; - struct sockaddr_in sin, from; - fd_set reads; - long oldmask; - pid_t pid; - int s, lport, timo; - char c; - - pid = getpid(); - hp = gethostbyname(*ahost); - if (hp == NULL) { - herror(*ahost); - return (-1); - } - *ahost = hp->h_name; - oldmask = sigblock(sigmask(SIGURG)); - for (timo = 1, lport = IPPORT_RESERVED - 1;;) { - s = rresvport(&lport); - if (s < 0) { - if (errno == EAGAIN) - (void)fprintf(stderr, - "rcmd: socket: All ports in use\n"); - else - (void)fprintf(stderr, "rcmd: socket: %s\n", - strerror(errno)); - sigsetmask(oldmask); - return (-1); - } - fcntl(s, F_SETOWN, pid); - sin.sin_family = hp->h_addrtype; - bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); - sin.sin_port = rport; - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) - break; - (void)close(s); - if (errno == EADDRINUSE) { - lport--; - continue; - } - if (errno == ECONNREFUSED && timo <= 16) { - (void)sleep(timo); - timo *= 2; - continue; - } - if (hp->h_addr_list[1] != NULL) { - int oerrno = errno; - - (void)fprintf(stderr, "connect to address %s: ", - inet_ntoa(sin.sin_addr)); - errno = oerrno; - perror(0); - hp->h_addr_list++; - bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); - (void)fprintf(stderr, "Trying %s...\n", - inet_ntoa(sin.sin_addr)); - continue; - } - (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno)); - sigsetmask(oldmask); - return (-1); - } - lport--; - if (fd2p == 0) { - write(s, "", 1); - lport = 0; - } else { - char num[8]; - int s2 = rresvport(&lport), s3; - int len = sizeof(from); - - if (s2 < 0) - goto bad; - listen(s2, 1); - (void)snprintf(num, sizeof(num), "%d", lport); - if (write(s, num, strlen(num)+1) != strlen(num)+1) { - (void)fprintf(stderr, - "rcmd: write (setting up stderr): %s\n", - strerror(errno)); - (void)close(s2); - goto bad; - } - FD_ZERO(&reads); - FD_SET(s, &reads); - FD_SET(s2, &reads); - errno = 0; - if (select(32, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)) { - if (errno != 0) - (void)fprintf(stderr, - "rcmd: select (setting up stderr): %s\n", - strerror(errno)); - else - (void)fprintf(stderr, - "select: protocol failure in circuit setup\n"); - (void)close(s2); - goto bad; - } - s3 = accept(s2, (struct sockaddr *)&from, &len); - (void)close(s2); - if (s3 < 0) { - (void)fprintf(stderr, - "rcmd: accept: %s\n", strerror(errno)); - lport = 0; - goto bad; - } - *fd2p = s3; - from.sin_port = ntohs((u_short)from.sin_port); - if (from.sin_family != AF_INET || - from.sin_port >= IPPORT_RESERVED || - from.sin_port < IPPORT_RESERVED / 2) { - (void)fprintf(stderr, - "socket: protocol failure in circuit setup.\n"); - goto bad2; - } - } - (void)write(s, locuser, strlen(locuser)+1); - (void)write(s, remuser, strlen(remuser)+1); - (void)write(s, cmd, strlen(cmd)+1); - if (read(s, &c, 1) != 1) { - (void)fprintf(stderr, - "rcmd: %s: %s\n", *ahost, strerror(errno)); - goto bad2; - } - if (c != 0) { - while (read(s, &c, 1) == 1) { - (void)write(STDERR_FILENO, &c, 1); - if (c == '\n') - break; - } - goto bad2; - } - sigsetmask(oldmask); - return (s); -bad2: - if (lport) - (void)close(*fd2p); -bad: - (void)close(s); - sigsetmask(oldmask); - return (-1); -} - -int -rresvport(alport) - int *alport; -{ - struct sockaddr_in sin; - int s; - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - return (-1); - for (;;) { - sin.sin_port = htons((u_short)*alport); - if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) - return (s); - if (errno != EADDRINUSE) { - (void)close(s); - return (-1); - } - (*alport)--; - if (*alport == IPPORT_RESERVED/2) { - (void)close(s); - errno = EAGAIN; /* close */ - return (-1); - } - } -} - -int __check_rhosts_file = 1; -char *__rcmd_errstr; - -int -ruserok(rhost, superuser, ruser, luser) - const char *rhost, *ruser, *luser; - int superuser; -{ - struct hostent *hp; - u_long addr; - char **ap; - - if ((hp = gethostbyname(rhost)) == NULL) - return (-1); - for (ap = hp->h_addr_list; *ap; ++ap) { - bcopy(*ap, &addr, sizeof(addr)); - if (iruserok(addr, superuser, ruser, luser) == 0) - return (0); - } - return (-1); -} - -/* - * New .rhosts strategy: We are passed an ip address. We spin through - * hosts.equiv and .rhosts looking for a match. When the .rhosts only - * has ip addresses, we don't have to trust a nameserver. When it - * contains hostnames, we spin through the list of addresses the nameserver - * gives us and look for a match. - * - * Returns 0 if ok, -1 if not ok. - */ -int -iruserok(raddr, superuser, ruser, luser) - u_long raddr; - int superuser; - const char *ruser, *luser; -{ - register char *cp; - struct stat sbuf; - struct passwd *pwd; - FILE *hostf; - uid_t uid; - int first; - char pbuf[MAXPATHLEN]; - - first = 1; - hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); -again: - if (hostf) { - if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { - (void)fclose(hostf); - return (0); - } - (void)fclose(hostf); - } - if (first == 1 && (__check_rhosts_file || superuser)) { - first = 0; - if ((pwd = getpwnam(luser)) == NULL) - return (-1); - (void)strcpy(pbuf, pwd->pw_dir); - (void)strcat(pbuf, "/.rhosts"); - - /* - * Change effective uid while opening .rhosts. If root and - * reading an NFS mounted file system, can't read files that - * are protected read/write owner only. - */ - uid = geteuid(); - (void)seteuid(pwd->pw_uid); - hostf = fopen(pbuf, "r"); - (void)seteuid(uid); - - if (hostf == NULL) - return (-1); - /* - * If not a regular file, or is owned by someone other than - * user or root or if writeable by anyone but the owner, quit. - */ - cp = NULL; - if (lstat(pbuf, &sbuf) < 0) - cp = ".rhosts lstat failed"; - else if (!S_ISREG(sbuf.st_mode)) - cp = ".rhosts not regular file"; - else if (fstat(fileno(hostf), &sbuf) < 0) - cp = ".rhosts fstat failed"; - else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) - cp = "bad .rhosts owner"; - else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) - cp = ".rhosts writeable by other than owner"; - /* If there were any problems, quit. */ - if (cp) { - __rcmd_errstr = cp; - (void)fclose(hostf); - return (-1); - } - goto again; - } - return (-1); -} - -/* - * XXX - * Don't make static, used by lpd(8). - * - * Returns 0 if ok, -1 if not ok. - */ -int -__ivaliduser(hostf, raddr, luser, ruser) - FILE *hostf; - u_long raddr; - const char *luser, *ruser; -{ - register char *user, *p; - int ch; - char buf[MAXHOSTNAMELEN + 128]; /* host + login */ - - while (fgets(buf, sizeof(buf), hostf)) { - p = buf; - /* Skip lines that are too long. */ - if (strchr(p, '\n') == NULL) { - while ((ch = getc(hostf)) != '\n' && ch != EOF); - continue; - } - while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { - *p = isupper(*p) ? tolower(*p) : *p; - p++; - } - if (*p == ' ' || *p == '\t') { - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - p++; - user = p; - while (*p != '\n' && *p != ' ' && - *p != '\t' && *p != '\0') - p++; - } else - user = p; - *p = '\0'; - if (__icheckhost(raddr, buf) && - strcmp(ruser, *user ? user : luser) == 0) { - return (0); - } - } - return (-1); -} - -/* - * Returns "true" if match, 0 if no match. - */ -static int -__icheckhost(raddr, lhost) - u_long raddr; - register char *lhost; -{ - register struct hostent *hp; - register u_long laddr; - register char **pp; - - /* Try for raw ip address first. */ - if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) - return (raddr == laddr); - - /* Better be a hostname. */ - if ((hp = gethostbyname(lhost)) == NULL) - return (0); - - /* Spin through ip addresses. */ - for (pp = hp->h_addr_list; *pp; ++pp) - if (!bcmp(&raddr, *pp, sizeof(u_long))) - return (1); - - /* No match. */ - return (0); -} diff --git a/gen/readdir_r.c b/gen/readdir_r.c deleted file mode 100644 index 8e19ccc..0000000 --- a/gen/readdir_r.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include - -/* - * Synopsis: - * dir_table is a global static array of pthread mutexes. The array is NMUTEXES - * in length (NMUTEXES * sizeof(pthread_mutex_t)). - * - * Whenever a call to readdir_r is made, the element in the array indexed by the - * modulus of the file descriptor associated with dirp is locked, and readdir is - * called on dirp. The result is returned in readdir_r semantics and the - * element in dir_table is unlocked. - */ - -static pthread_mutex_t dir_table[] = { - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER -#define NMUTEXES 8 -}; - -int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) -{ - int ret; - int mindex = dirp->dd_fd % NMUTEXES; - struct dirent *tmpdp; - - pthread_mutex_lock(&dir_table[mindex]); - - tmpdp = readdir(dirp); - if( tmpdp == NULL ) { - *result = NULL; - ret = errno; - pthread_mutex_unlock(&dir_table[mindex]); - return ret; - } - - memcpy(entry, tmpdp, sizeof(struct dirent)); - *result = entry; - - pthread_mutex_unlock(&dir_table[mindex]); - return 0; -} - - diff --git a/gen/scalable_malloc.c b/gen/scalable_malloc.c index b8c90ee..1a47195 100644 --- a/gen/scalable_malloc.c +++ b/gen/scalable_malloc.c @@ -27,750 +27,1942 @@ #import "scalable_malloc.h" -#define __POSIX_LIB__ +#import + #import -#import // for spin lock #import #include /********************* DEFINITIONS ************************/ -static unsigned vm_page_shift = 0; // guaranteed to be intialized by zone creation - #define DEBUG_MALLOC 0 // set to one to debug malloc itself + #define DEBUG_CLIENT 0 // set to one to help debug a nasty memory smasher #if DEBUG_MALLOC -#warning DEBUG ENABLED +#warning DEBUG_MALLOC ENABLED #define INLINE +#define CHECK_LOCKED(szone, fun) { \ + if (__is_threaded && TRY_LOCK(szone->lock)) { \ + malloc_printf("*** lock was not set %p in %s\n", szone->lock, fun); \ + } \ +} +#else +#define INLINE __inline__ +#define CHECK_LOCKED(szone, fun) {} +#endif + +#define PAGE_SIZE_FIXED 1 // flip if the page size becomes variable, one day +#if PAGE_SIZE_FIXED +#define vm_page_shift 12 #else -#define INLINE inline +static unsigned vm_page_shift = 0; // guaranteed to be intialized by zone creation #endif +typedef unsigned short msize_t; // a size in multiples of SHIFT_SMALL_QUANTUM or SHIFT_TINY_QUANTUM + +typedef struct { + unsigned checksum; + void *previous; + void *next; +} free_list_t; + +typedef struct { + unsigned address_and_num_pages; + // this type represents both an address and a number of pages + // the low bits are the number of pages; the high bits are the address + // note that the exact number of bits used for depends on the page size + // also, this cannot represent pointers larger than 1 << (vm_page_shift * 2) +} compact_range_t; + +typedef unsigned char grain_t; + #define CHECK_REGIONS (1 << 31) -#define VM_COPY_THRESHOLD (40 * 1024) - // When all memory is touched after a copy, vm_copy() is always a lose - // But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages (on a G3/300MHz) - // This must be larger than LARGE_THRESHOLD +#define CHECKSUM_MAGIC 0x357B -#define KILL_THRESHOLD (32 * 1024) +#define MAX_RECORDER_BUFFER 256 -#define LARGE_THRESHOLD (3 * vm_page_size) // at or above this use "large" +/********************* DEFINITIONS for tiny ************************/ -#define SHIFT_QUANTUM 4 // Required for AltiVec -#define QUANTUM (1 << SHIFT_QUANTUM) // allocation quantum -#define MIN_BLOCK 1 // minimum size, in QUANTUM multiples +#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec +#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM) -/* The header of a small block in use contains its size (expressed as multiples of QUANTUM, and header included), or 0; -If 0 then the block is either free (in which case the size is directly at the block itself), or the last block (indicated by either being beyond range, or having 0 in the block itself) */ +#define FOLLOWING_TINY_PTR(ptr,msize) (((char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM)) -#define PTR_HEADER_SIZE (sizeof(msize_t)) -#define FOLLOWING_PTR(ptr,msize) (((char *)(ptr)) + ((msize) << SHIFT_QUANTUM)) -#define PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-2] +#define NUM_TINY_SLOTS 32 // number of slots for free-lists -#define THIS_FREE 0x8000 // indicates this block is free -#define PREV_FREE 0x4000 // indicates previous block is free -#define MSIZE_FLAGS_FOR_PTR(ptr) (((msize_t *)(ptr))[-1]) +#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 TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + (NUM_TINY_BLOCKS >> 2) + 8 + (1 << vm_page_shift) - 1) & ~ ((1 << vm_page_shift) - 1)) // 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 REGION_SIZE (1 << (16 - 2 + SHIFT_QUANTUM)) // since we only have 16 bits for msize_t, and 1 bit is taken by THIS_FREE, and 1 by PREV_FREE +#define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[6]) +// At the end of free blocks, we stick the size (for enabling coalescing) +#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] -#define INITIAL_NUM_REGIONS 8 // must always be at least 2 to always have 1 slot empty -#define CHECKSUM_MAGIC 0x357B +#define TINY_REGION_ADDRESS(region) ((region) << TINY_BLOCKS_ALIGN) +#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region)+(1 << TINY_BLOCKS_ALIGN)) + +typedef unsigned short tiny_region_t; + +#define INITIAL_NUM_TINY_REGIONS 24 // must be even for szone to be aligned + +#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list + +#if ! TINY_CACHE +#warning TINY_CACHE turned off +#endif + +/********************* DEFINITIONS for small ************************/ + +/* We store the meta bits on the side in two bytes, as follows: +- high order bit SMALL_IS_FREE is set when the block is avail (and starts here) +- when block size, expressed in SMALL_QUANTUM, is the other 15 bits +- else 0 signifies this block is in the middle of another block +*/ + +#define SMALL_IS_FREE (1 << 15) + +#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9 +#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes + +#define FOLLOWING_SMALL_PTR(ptr,msize) (((char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM)) + +#define NUM_SMALL_SLOTS 32 // number of slots for free-lists + +#define SHIFT_NUM_SMALL_BLOCKS 14 // we can only represent up to 1<<15 for msize; but we chose to stay even below that to avoid the convention msize=0 => msize = (1<<15) +#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 SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] + +#define SMALL_REGION_ADDRESS(region) (((unsigned)region) << SMALL_BLOCKS_ALIGN) +#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region)+(1 << SMALL_BLOCKS_ALIGN)) + +typedef unsigned short 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 MAX_RECORDER_BUFFER 256 +#define SMALL_CACHE 1 +#if !SMALL_CACHE +#warning SMALL_CACHE turned off +#endif -#define MAX_GRAIN 128 +/********************* DEFINITIONS for large ************************/ -typedef unsigned short msize_t; // a size in multiples of SHIFT_QUANTUM +#define LARGE_THRESHOLD (15 * 1024) // at or above this use "large" -typedef struct { - unsigned checksum; - void *previous; - void *next; -} free_list_t; +#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM) +#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM +#endif -typedef struct { - unsigned address_and_num_pages; - // this type represents both an address and a number of pages - // the low bits are the number of pages - // the high bits are the address - // note that the exact number of bits used for depends on the page size - // also, this cannot represent pointers larger than 1 << (vm_page_shift * 2) -} compact_range_t; +#define VM_COPY_THRESHOLD (40 * 1024) + // When all memory is touched after a copy, vm_copy() is always a lose + // But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages (on a G3/300MHz) + // This must be larger than LARGE_THRESHOLD -typedef vm_address_t region_t; +#define LARGE_ENTRY_ADDRESS(entry) \ + (((entry).address_and_num_pages >> vm_page_shift) << vm_page_shift) +#define LARGE_ENTRY_NUM_PAGES(entry) \ + ((entry).address_and_num_pages & ((1 << vm_page_shift) - 1)) +#define LARGE_ENTRY_SIZE(entry) \ + (LARGE_ENTRY_NUM_PAGES(entry) << vm_page_shift) +#define LARGE_ENTRY_MATCHES(entry,ptr) \ + (!(((entry).address_and_num_pages - (unsigned)(ptr)) >> vm_page_shift)) +#define LARGE_ENTRY_IS_EMPTY(entry) (!((entry).address_and_num_pages)) typedef compact_range_t large_entry_t; +/********************* DEFINITIONS for huge ************************/ + typedef vm_range_t huge_entry_t; -typedef unsigned short grain_t; +/********************* zone itself ************************/ typedef struct { malloc_zone_t basic_zone; pthread_lock_t lock; unsigned debug_flags; void *log_address; - + + /* Regions for tiny objects */ + unsigned num_tiny_regions; + tiny_region_t *tiny_regions; + 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 + size_t tiny_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for + unsigned num_tiny_objects; + unsigned num_bytes_in_tiny_objects; + /* Regions for small objects */ - unsigned num_regions; - region_t *regions; - // this array is always created with 1 extra slot to be able to add a region without taking memory right away - unsigned last_region_hit; - free_list_t *free_list[MAX_GRAIN]; - unsigned num_bytes_free_in_last_region; // these bytes are cleared + unsigned num_small_regions; + small_region_t *small_regions; + 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]; + size_t small_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for unsigned num_small_objects; unsigned num_bytes_in_small_objects; - + /* large objects: vm_page_shift <= log2(size) < 2 *vm_page_shift */ unsigned num_large_objects_in_use; unsigned num_large_entries; + large_entry_t *large_entries; // hashed by location; null entries don't count unsigned num_bytes_in_large_objects; - large_entry_t *large_entries; - // large_entries are hashed by location - // large_entries that are 0 should be discarded /* huge objects: log2(size) >= 2 *vm_page_shift */ - unsigned num_bytes_in_huge_objects; - unsigned num_huge_entries; + unsigned char num_huge_entries; huge_entry_t *huge_entries; + unsigned 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]; } szone_t; static void *szone_malloc(szone_t *szone, size_t size); -static void *szone_valloc(szone_t *szone, size_t size); static INLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested); static void szone_free(szone_t *szone, void *ptr); -static size_t szone_good_size(szone_t *szone, size_t size); static boolean_t szone_check_all(szone_t *szone, const char *function); static void szone_print(szone_t *szone, boolean_t verbose); -static INLINE region_t *region_for_ptr_no_lock(szone_t *szone, const void *ptr); -static vm_range_t large_free_no_lock(szone_t *szone, large_entry_t *entry); +static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize); -#define LOG(szone,ptr) (szone->log_address && (szone->num_small_objects > 8) && (((unsigned)szone->log_address == -1) || (szone->log_address == (void *)(ptr)))) +#if DEBUG_MALLOC +#define LOG(szone,ptr) \ + (szone->log_address && (((unsigned)szone->log_address == -1) || (szone->log_address == (void *)(ptr)))) +#else +#define LOG(szone,ptr) 0 +#endif -/********************* ACCESSOR MACROS ************************/ +#define SZONE_LOCK(szone) { \ + LOCK(szone->lock); \ +} -#define SZONE_LOCK(szone) LOCK(szone->lock) -#define SZONE_UNLOCK(szone) UNLOCK(szone->lock) +#define SZONE_UNLOCK(szone) { \ + UNLOCK(szone->lock); \ +} -#define CHECK(szone,fun) if ((szone)->debug_flags & CHECK_REGIONS) szone_check_all(szone, fun) +#define LOCK_AND_NOTE_LOCKED(szone,locked) { \ + CHECK(szone, __PRETTY_FUNCTION__); \ + locked = 1; SZONE_LOCK(szone); \ +} -#define REGION_ADDRESS(region) (region) -#define REGION_END(region) (region+REGION_SIZE) +#if DEBUG_MALLOC || DEBUG_CLIENT +#define CHECK(szone,fun) \ + if ((szone)->debug_flags & CHECK_REGIONS) szone_check_all(szone, fun) +#else +#define CHECK(szone,fun) {} +#endif -#define LARGE_ENTRY_ADDRESS(entry) (((entry).address_and_num_pages >> vm_page_shift) << vm_page_shift) -#define LARGE_ENTRY_NUM_PAGES(entry) ((entry).address_and_num_pages & ((1 << vm_page_shift) - 1)) -#define LARGE_ENTRY_SIZE(entry) (LARGE_ENTRY_NUM_PAGES(entry) << vm_page_shift) -#define LARGE_ENTRY_MATCHES(entry,ptr) (!(((entry).address_and_num_pages - (unsigned)(ptr)) >> vm_page_shift)) -#define LARGE_ENTRY_IS_EMPTY(entry) (!((entry).address_and_num_pages)) +/********************* VERY LOW LEVEL UTILITIES ************************/ -/********************* VERY LOW LEVEL UTILITIES ************************/ +#if DEBUG_MALLOC || DEBUG_CLIENT +static void +szone_sleep(void) { + if (getenv("MallocErrorSleep")) { + malloc_printf("*** Sleeping to help debug\n"); + sleep(3600); // to help debug + } +} +#endif -static void szone_error(szone_t *szone, const char *msg, const void *ptr) { +static void +szone_error(szone_t *szone, const char *msg, const void *ptr) { if (szone) SZONE_UNLOCK(szone); if (ptr) { - malloc_printf("*** malloc[%d]: error for object %p: %s\n", getpid(), ptr, msg); -#if DEBUG_MALLOC - szone_print(szone, 1); -#endif + malloc_printf("*** malloc[%d]: error for object %p: %s\n", getpid(), ptr, msg); } else { - malloc_printf("*** malloc[%d]: error: %s\n", getpid(), msg); + malloc_printf("*** malloc[%d]: error: %s\n", getpid(), msg); } +#if DEBUG_MALLOC + szone_print(szone, 1); + szone_sleep(); +#endif #if DEBUG_CLIENT - malloc_printf("*** Sleeping to help debug\n"); - sleep(3600); // to help debug + szone_sleep(); #endif } -static void protect(szone_t *szone, vm_address_t address, vm_size_t size, unsigned protection, unsigned debug_flags) { +static void +protect(szone_t *szone, vm_address_t address, vm_size_t size, + unsigned protection, unsigned debug_flags) { kern_return_t err; if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) { - err = vm_protect(mach_task_self(), address - vm_page_size, vm_page_size, 0, protection); - if (err) malloc_printf("*** malloc[%d]: Can't protect(%x) region for prelude guard page at 0x%x\n", getpid(), protection, address - vm_page_size); + err = vm_protect(mach_task_self(), address - (1 << vm_page_shift), 1 << vm_page_shift, + 0, protection); + if (err) { + malloc_printf("*** malloc[%d]: Can't protect(%p) region for " + "prelude guard page at %p\n", getpid(), protection, + address - (1 << vm_page_shift)); + } } if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) { - err = vm_protect(mach_task_self(), (vm_address_t)(address + size), vm_page_size, 0, protection); - if (err) malloc_printf("*** malloc[%d]: Can't protect(%x) region for postlude guard page at 0x%x\n", getpid(), protection, address + size); + err = vm_protect(mach_task_self(), (vm_address_t)(address + size), 1 << vm_page_shift, 0, protection); + if (err) { + malloc_printf("*** malloc[%d]: Can't protect(%p) region for " + "postlude guard page at %p\n", getpid(), protection, + address + size); + } } } -static vm_address_t allocate_pages(szone_t *szone, size_t size, unsigned debug_flags, int vm_page_label) { +static vm_address_t +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 addr; boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; size_t allocation_size = round_page(size); - if (!allocation_size) allocation_size = vm_page_size; - if (add_guard_pages) allocation_size += 2 * vm_page_size; + 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 += 1 << align; err = vm_allocate(mach_task_self(), &addr, allocation_size, vm_page_label | 1); if (err) { - malloc_printf("*** malloc: vm_allocate(size=%d) failed with %d\n", size, err); - szone_error(szone, "Can't allocate region", NULL); - return NULL; + malloc_printf("*** malloc: vm_allocate(size=%d) failed (error code=%d)\n", size, err); + szone_error(szone, "Can't allocate region", NULL); + return NULL; + } + if (align) { + // malloc_printf("In allocate_pages(size=%d(%p), align=%d) -> %p\n", size, size, align, addr); + vm_address_t aligned_address = (addr + (1 << align) - 1) & ~ ((1 << align) - 1); + if (aligned_address != addr) { + size_t delta = aligned_address - addr; + err = vm_deallocate(mach_task_self(), addr, delta); + if (err) malloc_printf("*** malloc: freeing unaligned header failed with %d\n", err); + // malloc_printf("deallocated unaligned header %p length=%d(%p)\n", addr, delta, delta); + addr = aligned_address; + allocation_size -= delta; + } + if (allocation_size > size) { + err = vm_deallocate(mach_task_self(), addr+size, allocation_size - size); + if (err) malloc_printf("*** malloc: freeing unaligned footer failed with %d\n", err); + } } if (add_guard_pages) { - addr += vm_page_size; - protect(szone, addr, size, 0, debug_flags); + addr += 1 << vm_page_shift; + protect(szone, addr, size, 0, debug_flags); } return addr; } -static void deallocate_pages(szone_t *szone, vm_address_t addr, size_t size, unsigned debug_flags) { +static void +deallocate_pages(szone_t *szone, vm_address_t addr, size_t size, unsigned debug_flags) { kern_return_t err; boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; if (add_guard_pages) { - addr -= vm_page_size; - size += 2 * vm_page_size; + addr -= 1 << vm_page_shift; + size += 2 * (1 << vm_page_shift); } err = vm_deallocate(mach_task_self(), addr, size); if (err) { - szone_error(szone, "Can't deallocate_pages region", (void *)addr); + szone_error(szone, "Can't deallocate_pages region", (void *)addr); } } -static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { +static kern_return_t +_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { *ptr = (void *)address; return 0; } -/********************* FREE LIST UTILITIES ************************/ +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 + if (ptr->checksum != (((unsigned)ptr->previous) ^ ((unsigned)ptr->next) ^ CHECKSUM_MAGIC)) { +#if DEBUG_MALLOC + malloc_printf("*** Incorrect checksum: %s\n", msg); +#endif + szone_error(szone, "Incorrect checksum for freed object - object was probably modified after being freed; break at szone_error", ptr); + } +} + +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 + ptr->checksum = ((unsigned)ptr->previous) ^ ((unsigned)ptr->next) ^ CHECKSUM_MAGIC; +} + +static unsigned +free_list_count(const free_list_t *ptr) { + unsigned count = 0; + while (ptr) { + count++; +// malloc_printf("%p ", ptr); + ptr = ptr->next; + } + return count; +} + +#define BITMAP32_SET(bitmap,bit) (bitmap |= 1 << (bit)) +#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) + +/********************* TINY FREE LIST UTILITIES ************************/ + +// We encode the meta-headers as follows: +// Each quantum has an associated set of 2 bits: +// block_header when 1 says this block is the beginning of a block +// in_use when 1 says this block is in use +// so a block in use of size 3 is 1-1 0-X 0-X +// for a free block TINY_FREE_SIZE(ptr) carries the size and the bits are 1-0 X-X X-X +// for a block middle the bits are 0-0 + +// Attention double evaluation for these +#define BITARRAY_SET(bits,index) (bits[index>>3] |= (1 << (index & 7))) +#define BITARRAY_CLR(bits,index) (bits[index>>3] &= ~(1 << (index & 7))) +#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) { \ + 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))); \ + } \ +} + +#if 0 // Simple but slow version +#warning Slow version in effect +#define BITARRAY_MCLR(bits,index,num) { \ + unsigned _ctr = (num); \ + unsigned _cur = (index); \ + while (_ctr--) {BITARRAY_CLR(bits,_cur); _cur++; } \ +} +#else -static INLINE grain_t grain_for_msize(szone_t *szone, msize_t msize) { - // assumes msize >= MIN_BLOCK +// Following is for num <= 32 +#define BITARRAY_MCLR(bits,index,num) { \ + unsigned _index = (index); \ + unsigned char *_rebased = (bits) + (_index >> 3); \ + _index &= 7; \ + BITARRAY_MCLR_LESS_32(_rebased, _index, _index + (num)); \ +} +#endif + +static INLINE msize_t +get_tiny_meta_header(const void *ptr, boolean_t *is_free) { + // returns msize and is_free + // may return 0 for the msize component (meaning 65536) + unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN; + unsigned char *block_header = (unsigned char *)headers_start; + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); + unsigned byte_index = index >> 3; + block_header += byte_index; + index &= 7; + *is_free = 0; + if (!BITMAP32_BIT(*block_header, index)) return 0; + unsigned char *in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4; + if (!BITMAP32_BIT(*in_use, index)) { + *is_free = 1; + return TINY_FREE_SIZE(ptr); + } +#if defined(__BIG_ENDIAN__) + unsigned *addr = (void *)((unsigned)block_header & ~3); + unsigned word0 = OSReadSwapInt32(addr, 0); + unsigned word1 = OSReadSwapInt32(addr, 4); + unsigned bits = index + (((unsigned)block_header & 3) * 8); + unsigned word = (word0 >> bits) | (word1 << (32 - bits)); + unsigned result = ffs(word >> 1); +#if DEBUG_MALLOC + if (result >= 32) { + malloc_printf("*** get_tiny_meta_header() invariant broken %p %d\n", ptr, result); + szone_sleep(); + } +#endif + return result; +#else + unsigned cur = index + 1; + while (!BITARRAY_BIT(block_header, cur)) cur++; // assumes padding at the zone end #if DEBUG_MALLOC - if (msize < MIN_BLOCK) { - szone_error(szone, "grain_for_msize: msize too small", NULL); + if (cur - index >= 32) { + malloc_printf("*** get_tiny_meta_header() invariant broken %p %d %d\n", ptr, index, cur); + szone_sleep(); } #endif - return (msize < MAX_GRAIN + MIN_BLOCK) ? msize - MIN_BLOCK : MAX_GRAIN - 1; + return cur - index; +#endif } -static INLINE msize_t msize_for_grain(szone_t *szone, grain_t grain) { - // 0 if multiple sizes - return (grain < MAX_GRAIN - 1) ? grain + MIN_BLOCK : 0; +static INLINE void +set_tiny_meta_header_in_use(const void *ptr, msize_t msize) { + unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN; + unsigned char *block_header = (unsigned char *)headers_start; + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); +#if DEBUG_MALLOC + if (msize >= 32) malloc_printf("*** set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize); + if ((unsigned)index + (unsigned)msize > 0x10000) malloc_printf("*** set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize); +#endif + unsigned byte_index = index >> 3; + block_header += byte_index; + index &= 7; + BITMAP32_SET(*block_header, index); + unsigned char *in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4; + BITMAP32_SET(*in_use, index); + index++; + msize_t clr_msize = msize-1; + if (clr_msize) { + byte_index = index >> 3; + block_header += byte_index; in_use += byte_index; + index &= 7; + unsigned end_bit = index + clr_msize; + BITARRAY_MCLR_LESS_32(block_header, index, end_bit); + BITARRAY_MCLR_LESS_32(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 + boolean_t ff; + msize_t mf = get_tiny_meta_header(ptr, &ff); + if (msize != mf) { + malloc_printf("*** setting header for tiny in_use %p : %d\n", ptr, msize); + malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff); + } +#endif } -static INLINE void free_list_checksum(szone_t *szone, free_list_t *ptr) { - // We always checksum, as testing whether to do it (based on szone->debug_flags) is as fast as doing it - if (ptr->checksum != (((unsigned)ptr->previous) ^ ((unsigned)ptr->next) ^ CHECKSUM_MAGIC)) { - szone_error(szone, "Incorrect checksum for freed object - object was probably modified after being freed; break at szone_error", ptr); +static INLINE void +set_tiny_meta_header_middle(const void *ptr) { + // indicates this block is in the middle of an in use block + unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN; + unsigned char *block_header = (unsigned char *)headers_start; + unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4); + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); + BITARRAY_CLR(block_header, index); BITARRAY_CLR(in_use, index); + TINY_FREE_SIZE(ptr) = 0; +} + +static INLINE void +set_tiny_meta_header_free(const void *ptr, msize_t msize) { + // !msize is acceptable and means 65536 + unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN; + unsigned char *block_header = (unsigned char *)headers_start; + unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4); + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); +#if DEBUG_MALLOC + if ((unsigned)index + (unsigned)msize > 0x10000) { + 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; + } +#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); + } +#endif } -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 - ptr->checksum = ((unsigned)ptr->previous) ^ ((unsigned)ptr->next) ^ CHECKSUM_MAGIC; +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 short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN; + unsigned char *block_header = (unsigned char *)headers_start; + unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4); + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); + if (!BITARRAY_BIT(block_header, index)) return 0; + return !BITARRAY_BIT(in_use, index); +} + +static INLINE void * +tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) { + // returns the previous block, assuming and verifying it's free + unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN; + unsigned char *block_header = (unsigned char *)headers_start; + unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4); + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); + if (!index) return NULL; + msize_t previous_msize = TINY_PREVIOUS_MSIZE(ptr); + if (previous_msize > index) return NULL; + msize_t previous_index = index - previous_msize; + void *previous_ptr = (void *)((shifted_base << TINY_BLOCKS_ALIGN) + (previous_index << SHIFT_TINY_QUANTUM)); + if (TINY_FREE_SIZE(previous_ptr) != previous_msize) return NULL; + if (!BITARRAY_BIT(block_header, previous_index)) return NULL; + if (BITARRAY_BIT(in_use, previous_index)) return NULL; + // conservative check did match true check + *prev_msize = previous_msize; + // malloc_printf("tiny_previous_preceding_free(%p) -> %p,%d\n", ptr, previous_ptr, previous_msize); + return previous_ptr; } -static void free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { +static INLINE 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 header of the block properly - grain_t grain = grain_for_msize(szone, msize); + // 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->free_list[grain]; - msize_t *follower = (msize_t *)FOLLOWING_PTR(ptr, msize); + free_list_t *free_head = szone->tiny_free_list[slot]; #if DEBUG_MALLOC - if (LOG(szone,ptr)) malloc_printf("In free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize); - if (((unsigned)ptr) & (QUANTUM - 1)) { - szone_error(szone, "free_list_add_ptr: Unaligned ptr", ptr); + if (LOG(szone,ptr)) { + malloc_printf("In tiny_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize); + } + if (((unsigned)ptr) & (TINY_QUANTUM - 1)) { + szone_error(szone, "tiny_free_list_add_ptr: Unaligned ptr", ptr); } #endif - MSIZE_FLAGS_FOR_PTR(ptr) = msize | THIS_FREE; + set_tiny_meta_header_free(ptr, msize); if (free_head) { - free_list_checksum(szone, free_head); + 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, "free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr); - } - if (!(MSIZE_FLAGS_FOR_PTR(free_head) & THIS_FREE)) { - malloc_printf("ptr=%p grain=%d free_head=%p\n", ptr, grain, free_head); - szone_error(szone, "free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr); - } - if ((grain != MAX_GRAIN-1) && (MSIZE_FLAGS_FOR_PTR(free_head) != (THIS_FREE | msize))) { - malloc_printf("ptr=%p grain=%d free_head=%p previous_msize=%d\n", ptr, grain, free_head, MSIZE_FLAGS_FOR_PTR(free_head)); - szone_error(szone, "free_list_add_ptr: Internal invariant broken (incorrect msize)", ptr); - } -#endif - free_head->previous = free_ptr; - free_list_set_checksum(szone, free_head); + 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); + } +#endif + free_head->previous = free_ptr; + free_list_set_checksum(szone, free_head); + } else { + BITMAP32_SET(szone->tiny_bitmap, slot); } free_ptr->previous = NULL; free_ptr->next = free_head; free_list_set_checksum(szone, free_ptr); - szone->free_list[grain] = free_ptr; - // mark the end of this block - PREVIOUS_MSIZE(follower) = msize; - MSIZE_FLAGS_FOR_PTR(follower) |= PREV_FREE; + szone->tiny_free_list[slot] = free_ptr; + // malloc_printf("Setting head of free list for slot=%d to %p\n", slot, free_ptr); } -static void free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) { +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 - grain_t grain = grain_for_msize(szone, msize); + // 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; #if DEBUG_MALLOC - if (LOG(szone,ptr)) malloc_printf("In free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize); + if (LOG(szone,ptr)) { + malloc_printf("In tiny_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize); + } #endif - free_list_checksum(szone, free_ptr); + free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); if (!previous) { + // The block to remove is the head of the free list #if DEBUG_MALLOC - if (szone->free_list[grain] != ptr) { - malloc_printf("ptr=%p grain=%d msize=%d szone->free_list[grain]=%p\n", ptr, grain, msize, szone->free_list[grain]); - szone_error(szone, "free_list_remove_ptr: Internal invariant broken (szone->free_list[grain])", ptr); - return; - } + 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; + } #endif - szone->free_list[grain] = next; + szone->tiny_free_list[slot] = next; + if (!next) BITMAP32_CLR(szone->tiny_bitmap, slot); } else { - previous->next = next; - free_list_set_checksum(szone, previous); + previous->next = next; + free_list_set_checksum(szone, previous); } if (next) { - next->previous = previous; - free_list_set_checksum(szone, next); + next->previous = previous; + free_list_set_checksum(szone, next); } - MSIZE_FLAGS_FOR_PTR(FOLLOWING_PTR(ptr, msize)) &= ~ PREV_FREE; } -static boolean_t free_list_check(szone_t *szone, grain_t grain) { +static INLINE tiny_region_t * +tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) { + tiny_region_t *region = szone->tiny_regions; + unsigned num_regions = szone->num_tiny_regions; + unsigned ptr_shifted = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN; + while (num_regions--) { + tiny_region_t this = *region; + if (ptr_shifted == this) return region; + region++; + } + return NULL; +} + +static INLINE void +tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msize) { + size_t original_size = msize << SHIFT_TINY_QUANTUM; + void *next_block = ((char *)ptr + original_size); +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + 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); + } +#endif + // We try to coalesce this block with the preceeding one + msize_t previous_msize; + void *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); + } +#endif + tiny_free_list_remove_ptr(szone, previous, previous_msize); + ptr = previous; + msize += previous_msize; + } + // We try to coalesce with the next block + if (((vm_address_t)next_block < TINY_REGION_END(*region)) && tiny_meta_header_is_free(next_block)) { + // The next block is free, we coalesce + msize_t next_msize = 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); + } +#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 + // malloc_printf("Replacing %p(msize=%d) with %p(msize=%d) in freelist\n", next_block, next_msize, ptr, msize+next_msize); + msize += next_msize; + free_list_t *big_free_block = (free_list_t *)next_block; + free_list_t *after_next_block = big_free_block->next; + free_list_t *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 ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) { + memset(ptr, 0x55, msize << SHIFT_TINY_QUANTUM); + } + 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 + szone->num_tiny_objects--; + szone->num_bytes_in_tiny_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks +} + +static void * +tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize) { + // 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 + if (szone->tiny_bytes_free_at_end) { + tiny_region_t last_region = szone-> tiny_regions[szone->num_tiny_regions-1]; + void *last_block = (void *)(TINY_REGION_END(last_region) - szone->tiny_bytes_free_at_end); + tiny_free_list_add_ptr(szone, last_block, szone->tiny_bytes_free_at_end >> SHIFT_TINY_QUANTUM); + szone->tiny_bytes_free_at_end = 0; + } + void *ptr; + // time to create a new region + vm_address_t 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; + } + // malloc_printf("Allocated tiny region #%d: %p [%y]\n", szone->num_tiny_regions, aligned_address, TINY_REGION_SIZE); + // We set the padding after block_header to be all 1 + ((unsigned *)(aligned_address + (1 << TINY_BLOCKS_ALIGN) + (NUM_TINY_BLOCKS >> 3)))[0] = ~0; + if (szone->num_tiny_regions == INITIAL_NUM_TINY_REGIONS) { + tiny_region_t *new_regions; + // malloc_printf("=== Growing tiny_regions (%d regions)\n", szone->num_tiny_regions); + 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 >> TINY_BLOCKS_ALIGN; + szone->num_tiny_regions ++; // we set the number after the pointer is all ready to enable enumeration from another thread without taking the lock + ptr = (void *)aligned_address; + set_tiny_meta_header_in_use(ptr, msize); + szone->num_tiny_objects++; + szone->num_bytes_in_tiny_objects += msize << SHIFT_TINY_QUANTUM; + // We put a header on the last block so that it appears in use (for coalescing, etc...) + set_tiny_meta_header_in_use(ptr + (msize << SHIFT_TINY_QUANTUM), 1); + szone->tiny_bytes_free_at_end = (NUM_TINY_BLOCKS - msize) << SHIFT_TINY_QUANTUM; +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + malloc_printf("In tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + } +#endif + return ptr; +} + +static INLINE boolean_t +try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { + // returns 1 on success + msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1); + msize_t old_msize = old_size >> SHIFT_TINY_QUANTUM; + unsigned next_index = index + old_msize; + // malloc_printf("try_realloc_tiny_in_place %p %d %d\n", ptr, old_size, new_size); + if (next_index >= NUM_TINY_BLOCKS) { + // malloc_printf("try_realloc_tiny_in_place can't take place at end %p %d %d %d\n", ptr, old_size, new_size, next_index); + return 0; + } + void *next_block = (char *)ptr + old_size; + SZONE_LOCK(szone); + boolean_t is_free = tiny_meta_header_is_free(next_block); + if (!is_free) { + SZONE_UNLOCK(szone); + return 0; // next_block is in use; + } + msize_t next_msize = TINY_FREE_SIZE(next_block); + if (old_size + (next_msize >> SHIFT_TINY_QUANTUM) < new_size) { + // malloc_printf("try_realloc_tiny_in_place can't %p too small %d\n", next_block, next_msize); + SZONE_UNLOCK(szone); + return 0; // even with next block, not enough + } + 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_t coalesced_msize = (new_size - old_size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM; + msize_t leftover_msize = next_msize - coalesced_msize; + // malloc_printf("Realloc in place for %p; current size=%d next_msize=%d wanted=%d\n", ptr, old_size, next_msize, new_size); + if (leftover_msize) { + void *leftover = next_block + (coalesced_msize << SHIFT_TINY_QUANTUM); + // malloc_printf("Leftover in realloc in place %p leftover_msize=%d\n", leftover, leftover_msize); + tiny_free_list_add_ptr(szone, leftover, leftover_msize); + } + set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize); +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + malloc_printf("In try_realloc_tiny_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize); + } +#endif + szone->num_bytes_in_tiny_objects += coalesced_msize << SHIFT_TINY_QUANTUM; + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + // malloc_printf("Extended ptr %p for realloc old=%d desired=%d new=%d leftover=%d\n", ptr, (unsigned)old_size, (unsigned)new_size, (unsigned)szone_size(szone, ptr), leftover_msize << SHIFT_TINY_QUANTUM); + return 1; +} + +static boolean_t +szone_check_tiny_region(szone_t *szone, tiny_region_t *region) { + vm_address_t start = TINY_REGION_ADDRESS(*region); + void *ptr = (void *)start; + vm_address_t region_end = TINY_REGION_END(*region); + boolean_t prev_free = 0; + if (region == szone->tiny_regions + szone->num_tiny_regions - 1) region_end -= szone->tiny_bytes_free_at_end; + // malloc_printf("szone_check_tiny_region: szone=%p region=%p start=%p ptr=%p region_end=%p\n", szone, region, start, ptr, region_end); + while ((vm_address_t)ptr < region_end) { + boolean_t is_free; + msize_t msize = get_tiny_meta_header(ptr, &is_free); + if (is_free && !msize && (ptr == (void *)start)) { + // the entire region is free + return 1; + } + // malloc_printf("tiny %p [%d %d]\n", ptr, msize, is_free); + if (! msize) { + malloc_printf("*** malloc[%d]: invariant broken for tiny block %p this msize=%d - size is too small\n", getpid(), ptr, msize); + return 0; + } + if (!is_free) { + // this block is in use + prev_free = 0; + if (msize > 31*TINY_QUANTUM) { + malloc_printf("*** malloc[%d]: invariant broken for %p this tiny msize=%d[%p] - size is too large\n", getpid(), ptr, msize, msize); + return 0; + } + ptr += msize << SHIFT_TINY_QUANTUM; + } else { + // free pointer + if (prev_free) { + malloc_printf("*** malloc[%d]: invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n", getpid(), ptr, msize); + return 0; + } + prev_free = 1; + free_list_t *free_head = ptr; + free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); + if (free_head->previous && !tiny_meta_header_is_free(free_head->previous)) { + malloc_printf("*** malloc[%d]: invariant broken for %p (previous %p is not a free pointer)\n", getpid(), ptr, free_head->previous); + return 0; + } + if (free_head->next && !tiny_meta_header_is_free(free_head->next)) { + malloc_printf("*** malloc[%d]: invariant broken for %p (next in free list %p is not a free pointer)\n", getpid(), ptr, free_head->next); + return 0; + } + void *follower = FOLLOWING_TINY_PTR(ptr, msize); + if ((follower != (void *)region_end) && (TINY_PREVIOUS_MSIZE(follower) != msize)) { + malloc_printf("*** malloc[%d]: invariant broken for tiny free %p followed by %p in region [%p-%p] (end marker incorrect) should be %d; in fact %d\n", getpid(), ptr, follower, TINY_REGION_ADDRESS(*region), region_end, msize, TINY_PREVIOUS_MSIZE(follower)); + return 0; + } + ptr = follower; + } + } + if (ptr != (void *)region_end) { + malloc_printf("*** malloc[%d]: invariant broken for region end %p - %p\n", getpid(), ptr, region_end); + return 0; + } + if (region == szone->tiny_regions + szone->num_tiny_regions - 1) { + if (szone->tiny_bytes_free_at_end) { + boolean_t is_free; + msize_t msize = get_tiny_meta_header(ptr, &is_free); + if (is_free || (msize != 1)) { + malloc_printf("*** malloc[%d]: invariant broken for blocker block %p - %d %d\n", getpid(), ptr, msize, is_free); + } + } + } + return 1; +} + +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_region_t *regions; + unsigned index = 0; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + unsigned count = 0; + kern_return_t err; + 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; + tiny_region_t region = regions[index]; + vm_range_t range = {TINY_REGION_ADDRESS(region), TINY_REGION_SIZE}; + // malloc_printf("Enumerating tiny ptrs for tiny region starting at %p\n", range.address); + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + vm_range_t admin_range = {range.address + (1 << TINY_BLOCKS_ALIGN), 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)) { + vm_range_t ptr_range = {range.address, 1 << TINY_BLOCKS_ALIGN}; + recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); + } + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + unsigned char *mapped_region; + err = reader(task, range.address, range.size, (void **)&mapped_region); + if (err) return err; + unsigned char *block_header = (unsigned char *)(mapped_region + (1 << TINY_BLOCKS_ALIGN)); + unsigned char *in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4; + unsigned block_index = 0; + unsigned block_limit = NUM_TINY_BLOCKS; + if (index == num_regions - 1) + block_limit -= (tiny_bytes_free_at_end >> SHIFT_TINY_QUANTUM); + while (block_index < block_limit) { + boolean_t is_free = ! BITARRAY_BIT(in_use, block_index); + msize_t msize; + if (is_free) { + void *mapped_ptr = mapped_region + (block_index << SHIFT_TINY_QUANTUM); + msize = TINY_FREE_SIZE(mapped_ptr); + // printf("free: index=%x mapped=%p true_addr=%p msize=%d\n", block_index, mapped_ptr, (void *)range.address + (block_index << SHIFT_TINY_QUANTUM), msize); + // num_free++; + if (!msize) break; + } else { + msize = 1; + unsigned bit = block_index + 1; + while (! BITARRAY_BIT(block_header, bit)) { bit++; msize ++; } + // printf("in_use: index=%x true_addr=%p msize=%d\n", block_index, (void *)range.address + (block_index << SHIFT_TINY_QUANTUM), msize); + // num_in_use++; + buffer[count].address = range.address + (block_index << SHIFT_TINY_QUANTUM); + buffer[count].size = msize << SHIFT_TINY_QUANTUM; + count++; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } + block_index += msize; + } + } + // malloc_printf("Found in tiny region %d in_use and %d free\n", num_in_use, num_free); + index++; + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + } + return 0; +} + +static INLINE void * +tiny_malloc_from_free_list(szone_t *szone, msize_t msize) { + // Assumes we've locked the region + void *ptr; + 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; + ptr = *the_slot; + if (ptr) { + free_list_t *next; + next = ((free_list_t *)ptr)->next; + if (next) { + next->previous = NULL; + free_list_set_checksum(szone, next); + } + *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); + } +#endif + goto return_tiny_alloc; + } + // adjust slot based on bitmap + unsigned bitmap = szone->tiny_bitmap & ~ ((1 << slot) - 1); + if (! bitmap) goto try_tiny_malloc_from_end; + slot = BITMAP32_FFS(bitmap) - 1; + free_list_t **limit = free_list + NUM_TINY_SLOTS - 1; + free_list += slot; + while (free_list < limit) { + // try bigger grains + ptr = *free_list; + if (ptr) { + free_list_t *next; + next = ((free_list_t *)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 = *limit; + if (ptr) { + free_list_t *next; + this_msize = TINY_FREE_SIZE(ptr); + next = ((free_list_t *)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 + // malloc_printf("Allocation from largest tiny slot %p optimized\n", ptr); + msize_t leftover_msize = this_msize - msize; + void *leftover_ptr = ptr + (msize << SHIFT_TINY_QUANTUM); + *limit = leftover_ptr; + if (next) { + next->previous = leftover_ptr; + free_list_set_checksum(szone, next); + } + ((free_list_t *)leftover_ptr)->next = next; + ((free_list_t *)leftover_ptr)->previous = NULL; + free_list_set_checksum(szone, leftover_ptr); + 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); + } +#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; + } +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 >= (msize << SHIFT_TINY_QUANTUM)) { + ptr = (void *)(TINY_REGION_END(szone->tiny_regions[szone->num_tiny_regions-1]) - szone->tiny_bytes_free_at_end); + szone->tiny_bytes_free_at_end -= msize << SHIFT_TINY_QUANTUM; + 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(ptr + (msize << SHIFT_TINY_QUANTUM), 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); + } +#endif + goto return_tiny_alloc; + } + return NULL; +add_leftover_and_proceed: + // malloc_printf("For msize=%d found tiny in free_list (slot=%d) this_msize=%d\n", msize, free_list - szone->tiny_free_list, this_msize); + if (!this_msize || (this_msize > msize)) { + msize_t leftover_msize = this_msize - msize; + void *leftover_ptr = ptr + (msize << SHIFT_TINY_QUANTUM); +#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); + } +#endif + 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 += this_msize << SHIFT_TINY_QUANTUM; +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + malloc_printf("In tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); + } +#endif + set_tiny_meta_header_in_use(ptr, this_msize); + return ptr; +} + +static INLINE void * +tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) { + boolean_t locked = 0; + void *ptr; +#if DEBUG_MALLOC + if (! msize) { + szone_error(szone, "Invariant broken (!msize) in allocation (region)", NULL); + } +#endif +#if TINY_CACHE + ptr = (void *)szone->last_tiny_free; + if ((((unsigned)ptr) & (TINY_QUANTUM - 1)) == msize) { + // we have a candidate - let's lock to make sure + LOCK_AND_NOTE_LOCKED(szone, locked); + if (ptr == (void *)szone->last_tiny_free) { + szone->last_tiny_free = NULL; + // malloc_printf("using last_tiny_free\n"); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + ptr = (void *)((unsigned)ptr & ~ (TINY_QUANTUM - 1)); + if (cleared_requested) { + memset(ptr, 0, msize << SHIFT_TINY_QUANTUM); + } +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + malloc_printf("In tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize); + } +#endif + return ptr; + } + // malloc_printf("optimistic locking for last_tiny_free failed\n"); + } +#endif + // Except in rare occasions where we need to add a new region, we are going to end up locking, so we might as well lock right away to avoid doing unnecessary optimistic probes + if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked); + ptr = tiny_malloc_from_free_list(szone, msize); + // malloc_printf("tiny_malloc_from_free_list(%d) returned %p\n", msize, ptr); + if (ptr) { + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, msize << SHIFT_TINY_QUANTUM); + } + return ptr; + } + ptr = tiny_malloc_from_region_no_lock(szone, msize); + // malloc_printf("tiny_malloc_from_region_no_lock returned %p for msize=%d\n", ptr, msize); + // we don't clear because this freshly allocated space is pristine + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + return ptr; +} + +static INLINE void +free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) { + // ptr is known to be in tiny_region + SZONE_LOCK(szone); +#if TINY_CACHE + void *ptr2 = szone->last_tiny_free; + if (ptr == (void *)((unsigned)ptr2 & ~ (TINY_QUANTUM - 1))) { + szone_error(szone, "Double free", ptr); + return; + } +#endif /* TINY_CACHE */ + boolean_t is_free; + msize_t msize = get_tiny_meta_header(ptr, &is_free); + if (is_free) { + szone_error(szone, "Double free", ptr); + return; + } + // malloc_printf("%p[%x]\n", ptr, msize); +#if DEBUG_MALLOC + if (!msize) { + malloc_printf("*** szone_free() block in use is too large: %p\n", ptr); + } +#endif +#if TINY_CACHE + if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits + szone->last_tiny_free = (void *)(((unsigned)ptr) | msize); + if (!ptr2) { + // malloc_printf("stuffing last_tiny_free\n"); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + return; + } + // malloc_printf("replacing previous last_tiny_free %p with %p\n", ptr2, szone->last_tiny_free); + msize = (unsigned)ptr2 & (TINY_QUANTUM - 1); + ptr = (void *)(((unsigned)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); + } + } +#endif + tiny_free_no_lock(szone, tiny_region, ptr, msize); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); +} + +static void +print_tiny_free_list(szone_t *szone) { + grain_t slot = 0; + malloc_printf("Tiny free sizes: "); + while (slot < NUM_TINY_SLOTS) { + free_list_t *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)); + } + slot++; + } + malloc_printf("\n"); +} + +static void +print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end) { + unsigned counts[1024]; + unsigned in_use = 0; + vm_address_t start = TINY_REGION_ADDRESS(region); + vm_address_t current = start; + vm_address_t limit = TINY_REGION_END(region) - bytes_at_end; + memset(counts, 0, 1024 * sizeof(unsigned)); + while (current < limit) { + boolean_t is_free; + msize_t msize = get_tiny_meta_header((void *)current, &is_free); + // malloc_printf("%p [%d %d]; ", current, msize, is_free); + if (is_free & !msize && (current == start)) { + // first block is all free + break; + } + if (!msize) { + malloc_printf("*** Error with %p: msize=%d\n", current, msize); + break; + } + if (! is_free) { + // block in use + if (msize > 32) malloc_printf("*** Error at %p msize for in_use is %d\n", current, msize); + if (msize < 1024) counts[msize]++; + in_use++; + } + current += msize << SHIFT_TINY_QUANTUM; + } + malloc_printf("Tiny region [%p-%p, %y]\t", 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) { + unsigned ci = 0; + malloc_printf("\n\tSizes in use: "); + while (ci < 1024) { + if (counts[ci]) { + malloc_printf("%d[%d] ", ci << SHIFT_TINY_QUANTUM, counts[ci]); + } + ci++; + } + } + malloc_printf("\n"); +} + +static boolean_t +tiny_free_list_check(szone_t *szone, grain_t slot) { + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); unsigned count = 0; - free_list_t *ptr = szone->free_list[grain]; + free_list_t *ptr = szone->tiny_free_list[slot]; free_list_t *previous = NULL; while (ptr) { - msize_t msize_and_free = MSIZE_FLAGS_FOR_PTR(ptr); - count++; - if (!(msize_and_free & THIS_FREE)) { - malloc_printf("*** malloc[%d]: In-use ptr in free list grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); - return 0; - } - if (((unsigned)ptr) & (QUANTUM - 1)) { - malloc_printf("*** malloc[%d]: Unaligned ptr in free list grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); - return 0; - } - if (!region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** malloc[%d]: Ptr not in szone grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); - return 0; - } - free_list_checksum(szone, ptr); - if (ptr->previous != previous) { - malloc_printf("*** malloc[%d]: Previous incorrectly set grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); - return 0; - } - if ((grain != MAX_GRAIN-1) && (msize_and_free != (msize_for_grain(szone, grain) | THIS_FREE))) { - malloc_printf("*** malloc[%d]: Incorrect msize for grain=%d count=%d ptr=%p msize=%d\n", getpid(), grain, count, ptr, msize_and_free); - return 0; - } - previous = ptr; - ptr = ptr->next; + free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); + boolean_t is_free = tiny_meta_header_is_free(ptr); + if (! is_free) { + malloc_printf("*** malloc[%d]: In-use ptr in free list slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr); + return 0; + } + if (((unsigned)ptr) & (TINY_QUANTUM - 1)) { + malloc_printf("*** malloc[%d]: Unaligned ptr in free list slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr); + return 0; + } + if (!tiny_region_for_ptr_no_lock(szone, ptr)) { + malloc_printf("*** malloc[%d]: Ptr not in szone slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr); + return 0; + } + if (ptr->previous != previous) { + malloc_printf("*** malloc[%d]: Previous incorrectly set slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr); + return 0; + } + previous = ptr; + ptr = ptr->next; + count++; } + // malloc_printf("tiny_free_list_check passed\n"); return 1; } -/********************* SMALL BLOCKS MANAGEMENT ************************/ +/********************* SMALL FREE LIST UTILITIES ************************/ + +static INLINE msize_t * +small_meta_headers(const void *ptr) { + // returns address of meta info + unsigned short shifted_base = ((unsigned)ptr) >> SMALL_BLOCKS_ALIGN; + unsigned headers_start = (shifted_base + 1) << SMALL_BLOCKS_ALIGN; + return (msize_t *)headers_start; +} + +static INLINE msize_t +small_meta_index(const void *ptr) { + // returns address of meta info + return (((unsigned)ptr) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_BLOCKS - 1); +} + +static INLINE msize_t * +small_meta_header(const void *ptr) { + // returns address of meta info + msize_t *meta_headers = small_meta_headers(ptr); + msize_t index = small_meta_index(ptr); + return meta_headers + index; +} + +static INLINE void +small_meta_header_set_is_free(msize_t *meta_headers, msize_t index, msize_t msize) { + // Indicates that the meta_header for index says 'is free' + meta_headers[index] = msize | SMALL_IS_FREE; +} + +static INLINE void +small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) { + // Indicates that the meta_header for index says 'in use' + meta_headers[index] = msize; +} + +static INLINE void +small_meta_header_set_middle(msize_t *meta_headers, msize_t index) { + // Indicates that the meta_header for index says 'in the middle of a block' + meta_headers[index] = 0; +} -static INLINE region_t *region_for_ptr_no_lock(szone_t *szone, const void *ptr) { - region_t *first_region = szone->regions; - region_t *region = first_region + szone->last_region_hit; - region_t this = *region; - if ((unsigned)ptr - (unsigned)REGION_ADDRESS(this) < (unsigned)REGION_SIZE) { - return region; +static void +small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { + // Adds an item to the proper free list + // Also marks the header of the block properly + // Assumes szone has been locked + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + grain_t grain = (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]; +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + malloc_printf("In small_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize); + } + if (((unsigned)ptr) & (SMALL_QUANTUM - 1)) { + szone_error(szone, "small_free_list_add_ptr: Unaligned ptr", ptr); + } +#endif + if (free_head) { + 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_meta_header(free_head)[0] & SMALL_IS_FREE)) { + 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); + } +#endif + free_head->previous = free_ptr; + free_list_set_checksum(szone, free_head); } else { - // We iterate in reverse order becase last regions are more likely - region = first_region + szone->num_regions; - while (region != first_region) { - this = *(--region); - if ((unsigned)ptr - (unsigned)REGION_ADDRESS(this) < (unsigned)REGION_SIZE) { - szone->last_region_hit = region - first_region; - return region; - } - } - return NULL; - } -} - -static INLINE void small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize_and_free) { - msize_t msize = msize_and_free & ~ PREV_FREE; - size_t original_size = msize << SHIFT_QUANTUM; - void *next_block = ((char *)ptr + original_size); - msize_t next_msize_and_free; + BITMAP32_SET(szone->small_bitmap, grain); + } + free_ptr->previous = NULL; + free_ptr->next = free_head; + free_list_set_checksum(szone, free_ptr); + szone->small_free_list[grain] = free_ptr; + void *follower = ptr + (msize << SHIFT_SMALL_QUANTUM); + SMALL_PREVIOUS_MSIZE(follower) = msize; +} + +static void +small_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 + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + 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; #if DEBUG_MALLOC - if (LOG(szone,ptr)) malloc_printf("In small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - if (msize < MIN_BLOCK) { - 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); - } -#endif - if (((vm_address_t)next_block < REGION_END(*region)) && ((next_msize_and_free = MSIZE_FLAGS_FOR_PTR(next_block)) & THIS_FREE)) { - // If the next block is free, we coalesce - msize_t next_msize = next_msize_and_free & ~THIS_FREE; - if (LOG(szone,ptr)) malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize); - free_list_remove_ptr(szone, next_block, next_msize); - msize += next_msize; - } - // Let's try to coalesce backwards now - if (msize_and_free & PREV_FREE) { - msize_t previous_msize = PREVIOUS_MSIZE(ptr); - void *previous = ptr - (previous_msize << SHIFT_QUANTUM); + if (LOG(szone,ptr)) { + malloc_printf("In small_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize); + } +#endif + free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); + if (!previous) { #if DEBUG_MALLOC - if (LOG(szone,previous)) malloc_printf("In small_free_no_lock(), coalesced backwards for %p previous=%p, msize=%d\n", ptr, previous, previous_msize); - if (!previous_msize || (previous_msize >= (((vm_address_t)ptr - REGION_ADDRESS(*region)) >> SHIFT_QUANTUM))) { - szone_error(szone, "Invariant 1 broken when coalescing backwards", ptr); - } - if (MSIZE_FLAGS_FOR_PTR(previous) != (previous_msize | THIS_FREE)) { - malloc_printf("previous=%p its_msize_and_free=0x%x previous_msize=%d\n", previous, MSIZE_FLAGS_FOR_PTR(previous), previous_msize); - szone_error(szone, "Invariant 3 broken when coalescing backwards", ptr); - } -#endif - free_list_remove_ptr(szone, previous, previous_msize); - ptr = previous; - msize += previous_msize; + 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; + } +#endif + szone->small_free_list[grain] = next; + if (!next) BITMAP32_CLR(szone->small_bitmap, grain); + } else { + previous->next = next; + free_list_set_checksum(szone, previous); + } + if (next) { + next->previous = previous; + free_list_set_checksum(szone, next); + } +} + +static INLINE small_region_t * +small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) { + small_region_t *region = szone->small_regions; + unsigned num_regions = szone->num_small_regions; + unsigned ptr_shifted = ((unsigned)ptr) >> SMALL_BLOCKS_ALIGN; + while (num_regions--) { + small_region_t this = *region; + if (ptr_shifted == this) return region; + region++; + } + return NULL; +} + +static INLINE void +small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t msize) { + // Assumes locked + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + msize_t *meta_headers = small_meta_headers(ptr); + msize_t index = small_meta_index(ptr); + size_t original_size = msize << SHIFT_SMALL_QUANTUM; + void *next_block = ((char *)ptr + original_size); + msize_t next_index = index + msize; +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + 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); + } + // printf("In small_free_no_lock %p - msize=%d\n", ptr, msize); +#endif + // We try to coalesce this block with the preceeding one + if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) { + msize_t previous_msize = SMALL_PREVIOUS_MSIZE(ptr); + if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) { + void *previous = ptr - (previous_msize << SHIFT_SMALL_QUANTUM); + // previous is really to be coalesced #if DEBUG_MALLOC - if (msize & PREV_FREE) { - malloc_printf("In small_free_no_lock(), after coalescing with previous ptr=%p, msize=%d previous_msize=%d\n", ptr, msize, previous_msize); - szone_error(szone, "Incorrect coalescing", ptr); + if (LOG(szone, ptr) || LOG(szone,previous)) { + malloc_printf("In small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); + } +#endif + // malloc_printf("In small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); + small_free_list_remove_ptr(szone, previous, previous_msize); + small_meta_header_set_middle(meta_headers, index); + ptr = previous; + msize += previous_msize; + index -= previous_msize; } -#endif + } + // We try to coalesce with the next block + if (((vm_address_t)next_block < SMALL_REGION_END(*region)) && (meta_headers[next_index] & SMALL_IS_FREE)) { + // next block is free, we coalesce + msize_t next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE; +#if DEBUG_MALLOC + if (LOG(szone,ptr)) malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize); +#endif + // malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize); + small_free_list_remove_ptr(szone, next_block, next_msize); + small_meta_header_set_middle(meta_headers, next_index); + msize += next_msize; } if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) { if (!msize) { szone_error(szone, "Incorrect size information - block header was damaged", ptr); } else { - memset(ptr, 0x55, (msize << SHIFT_QUANTUM) - PTR_HEADER_SIZE); + memset(ptr, 0x55, (msize << SHIFT_SMALL_QUANTUM)); } } - free_list_add_ptr(szone, ptr, msize); - CHECK(szone, "small_free_no_lock: added to free list"); + small_free_list_add_ptr(szone, ptr, msize); + small_meta_header_set_is_free(meta_headers, index, msize); szone->num_small_objects--; szone->num_bytes_in_small_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks } -static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize) { +static void * +small_malloc_from_region_no_lock(szone_t *szone, msize_t msize) { // Allocates from the last region or a freshly allocated region - region_t *last_region = szone->regions + szone->num_regions - 1; - vm_address_t new_address; - void *ptr; - msize_t msize_and_free; - unsigned region_capacity; - ptr = (void *)(REGION_END(*last_region) - szone->num_bytes_free_in_last_region + PTR_HEADER_SIZE); -#if DEBUG_MALLOC - if (((vm_address_t)ptr) & (QUANTUM - 1)) { - szone_error(szone, "Invariant broken while using end of region", ptr); - } -#endif - msize_and_free = MSIZE_FLAGS_FOR_PTR(ptr); -#if DEBUG_MALLOC - if (msize_and_free != PREV_FREE && msize_and_free != 0) { - malloc_printf("*** malloc[%d]: msize_and_free = %d\n", getpid(), msize_and_free); - szone_error(szone, "Invariant broken when allocating at end of zone", ptr); - } -#endif - // In order to make sure we don't have 2 free pointers following themselves, if the last item is a free item, we combine it and clear it - if (msize_and_free == PREV_FREE) { - msize_t previous_msize = PREVIOUS_MSIZE(ptr); - void *previous = ptr - (previous_msize << SHIFT_QUANTUM); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) malloc_printf("Combining last with free space at %p\n", ptr); - if (!previous_msize || (previous_msize >= (((vm_address_t)ptr - REGION_ADDRESS(*last_region)) >> SHIFT_QUANTUM)) || (MSIZE_FLAGS_FOR_PTR(previous) != (previous_msize | THIS_FREE))) { - szone_error(szone, "Invariant broken when coalescing backwards at end of zone", ptr); - } -#endif - free_list_remove_ptr(szone, previous, previous_msize); - szone->num_bytes_free_in_last_region += previous_msize << SHIFT_QUANTUM; - memset(previous, 0, previous_msize << SHIFT_QUANTUM); - MSIZE_FLAGS_FOR_PTR(previous) = 0; - ptr = previous; - } - // first try at the end of the last region - CHECK(szone, __PRETTY_FUNCTION__); - if (szone->num_bytes_free_in_last_region >= (msize << SHIFT_QUANTUM)) { - szone->num_bytes_free_in_last_region -= (msize << SHIFT_QUANTUM); - szone->num_small_objects++; - szone->num_bytes_in_small_objects += msize << SHIFT_QUANTUM; - MSIZE_FLAGS_FOR_PTR(ptr) = msize; - return ptr; + 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) { + small_region_t last_region = szone->small_regions[szone->num_small_regions - 1]; + void *last_block = (void *)(SMALL_REGION_END(last_region) - szone->small_bytes_free_at_end); + small_free_list_add_ptr(szone, last_block, szone->small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM); + small_meta_header(last_block)[0] = (szone->small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM) | SMALL_IS_FREE; + szone->small_bytes_free_at_end = 0; } + void *ptr; // time to create a new region - new_address = allocate_pages(szone, REGION_SIZE, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_SMALL)); + vm_address_t 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; - } - // let's prepare to free the remnants of last_region - if (szone->num_bytes_free_in_last_region >= QUANTUM) { - msize_t this_msize = szone->num_bytes_free_in_last_region >> SHIFT_QUANTUM; - // malloc_printf("Entering last block %p size=%d\n", ptr, this_msize << SHIFT_QUANTUM); - if (this_msize >= MIN_BLOCK) { - free_list_add_ptr(szone, ptr, this_msize); - } else { - // malloc_printf("Leaking last block at %p\n", ptr); - } - szone->num_bytes_free_in_last_region -= this_msize << SHIFT_QUANTUM; // to avoid coming back here - } - last_region[1] = new_address; - szone->num_regions++; - szone->num_bytes_free_in_last_region = REGION_SIZE - QUANTUM + PTR_HEADER_SIZE - (msize << SHIFT_QUANTUM); - ptr = (void *)(new_address + QUANTUM); // waste the first bytes - region_capacity = (MSIZE_FLAGS_FOR_PTR(szone->regions) * QUANTUM - PTR_HEADER_SIZE) / sizeof(region_t); - if (szone->num_regions >= region_capacity) { - unsigned new_capacity = region_capacity * 2 + 1; - msize_t new_msize = (new_capacity * sizeof(region_t) + PTR_HEADER_SIZE + QUANTUM - 1) / QUANTUM; - region_t *new_regions = ptr; - // malloc_printf("Now %d regions growing regions %p to %d\n", szone->num_regions, szone->regions, new_capacity); - MSIZE_FLAGS_FOR_PTR(new_regions) = new_msize; - szone->num_small_objects++; - szone->num_bytes_in_small_objects += new_msize << SHIFT_QUANTUM; - memcpy(new_regions, szone->regions, szone->num_regions * sizeof(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 - // Given that in practise the number of regions is typically a handful, this should not be a big deal - szone->regions = new_regions; - ptr += (new_msize << SHIFT_QUANTUM); - szone->num_bytes_free_in_last_region -= (new_msize << SHIFT_QUANTUM); - // malloc_printf("Regions is now %p next ptr is %p\n", szone->regions, ptr); - } + // out of memory! + return NULL; + } + ptr = (void *)new_address; + msize_t *meta_headers = small_meta_headers(ptr); + msize_t index = 0; + // malloc_printf("Allocated small region #%d: %p [%y]\n", szone->num_small_regions, new_address, SMALL_REGION_SIZE); + if (szone->num_small_regions == INITIAL_NUM_SMALL_REGIONS) { + // time to grow the number of regions + unsigned region_capacity = (1 << (32 - SMALL_BLOCKS_ALIGN)) - 20; // that is for sure the maximum number of small regions we can have + msize_t new_msize = (region_capacity * sizeof(small_region_t) + SMALL_QUANTUM - 1) / SMALL_QUANTUM; + small_region_t *new_regions = ptr; + // malloc_printf("Now %d small_regions growing regions %p to %d msize=%d\n", szone->num_small_regions + 1, szone->small_regions, region_capacity, new_msize); + small_meta_header_set_in_use(meta_headers, index, new_msize); + szone->num_small_objects++; + szone->num_bytes_in_small_objects += new_msize << SHIFT_SMALL_QUANTUM; + 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 += new_msize << SHIFT_SMALL_QUANTUM; + index = new_msize; + // malloc_printf("Regions is now %p next ptr is %p\n", szone->small_regions, ptr); + } + szone->small_regions[szone->num_small_regions] = new_address >> SMALL_BLOCKS_ALIGN; + szone->num_small_regions++; // we bump the number of regions AFTER we have changes the regions pointer to enable finding a small region without taking the lock + // malloc_printf("Now %d small regions\n", szone->num_small_regions); + small_meta_header_set_in_use(meta_headers, index, msize); + msize_t msize_left = NUM_SMALL_BLOCKS - index; szone->num_small_objects++; - szone->num_bytes_in_small_objects += msize << SHIFT_QUANTUM; - MSIZE_FLAGS_FOR_PTR(ptr) = msize; + szone->num_bytes_in_small_objects += msize << SHIFT_SMALL_QUANTUM; + // add a big free block + index += msize; msize_left -= msize; + meta_headers[index] = msize_left; + szone->small_bytes_free_at_end = msize_left << SHIFT_SMALL_QUANTUM; + // malloc_printf("small_bytes_free_at_end set to %d\n", szone-> small_bytes_free_at_end); return ptr; } -static boolean_t szone_check_region(szone_t *szone, region_t *region) { - void *ptr = (void *)REGION_ADDRESS(*region) + QUANTUM; - vm_address_t region_end = REGION_END(*region); - int is_last_region = region == szone->regions + szone->num_regions - 1; +static boolean_t +szone_check_small_region(szone_t *szone, small_region_t *region) { + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + void *ptr = (void *)SMALL_REGION_ADDRESS(*region); + msize_t *meta_headers = small_meta_headers(ptr); + vm_address_t region_end = SMALL_REGION_END(*region); msize_t prev_free = 0; + if (region == szone->small_regions + szone->num_small_regions - 1) region_end -= szone->small_bytes_free_at_end; while ((vm_address_t)ptr < region_end) { - msize_t msize_and_free = MSIZE_FLAGS_FOR_PTR(ptr); - if (!(msize_and_free & THIS_FREE)) { - msize_t msize = msize_and_free & ~PREV_FREE; - if ((msize_and_free & PREV_FREE) != prev_free) { - malloc_printf("*** malloc[%d]: invariant broken for %p (prev_free=%d) this msize=%d\n", getpid(), ptr, prev_free, msize_and_free); - return 0; - } - if (!msize) { - int extra = (is_last_region) ? szone->num_bytes_free_in_last_region : QUANTUM; - if (((unsigned)(ptr + extra)) < region_end) { - malloc_printf("*** malloc[%d]: invariant broken at region end: ptr=%p extra=%d index=%d num_regions=%d end=%p\n", getpid(), ptr, extra, region - szone->regions, szone->num_regions, (void *)region_end); - return 0; - } - break; // last encountered - } - if (msize > (LARGE_THRESHOLD / QUANTUM)) { - malloc_printf("*** malloc[%d]: invariant broken for %p this msize=%d - size is too large\n", getpid(), ptr, msize_and_free); - return 0; - } - if ((msize < MIN_BLOCK) && ((unsigned)ptr != region_end - QUANTUM)) { - malloc_printf("*** malloc[%d]: invariant broken for %p this msize=%d - size is too small\n", getpid(), ptr, msize_and_free); - return 0; - } - ptr += msize << SHIFT_QUANTUM; - prev_free = 0; - if (is_last_region && ((vm_address_t)ptr - PTR_HEADER_SIZE > region_end - szone->num_bytes_free_in_last_region)) { - malloc_printf("*** malloc[%d]: invariant broken for %p this msize=%d - block extends beyond allocated region\n", getpid(), ptr, msize_and_free); + msize_t index = small_meta_index(ptr); + msize_t msize_and_free = meta_headers[index]; + if (! (msize_and_free & SMALL_IS_FREE)) { + // block is in use + msize_t msize = msize_and_free; + if (!msize) { + malloc_printf("*** malloc[%d]: invariant broken: null msize ptr=%p region#=%d num_small_regions=%d end=%p\n", getpid(), ptr, region - szone->small_regions, szone->num_small_regions, (void *)region_end); + return 0; + } + if (msize > (LARGE_THRESHOLD / SMALL_QUANTUM)) { + malloc_printf("*** malloc[%d]: invariant broken for %p this small msize=%d - size is too large\n", getpid(), ptr, msize_and_free); + return 0; + } + ptr += msize << SHIFT_SMALL_QUANTUM; + prev_free = 0; + } else { + // free pointer + msize_t msize = msize_and_free & ~ SMALL_IS_FREE; + free_list_t *free_head = ptr; + msize_t *follower = (void *)FOLLOWING_SMALL_PTR(ptr, msize); + if (! msize) { + malloc_printf("*** malloc[%d]: invariant broken for free block %p this msize=%d\n", getpid(), ptr, msize); + return 0; + } + if (prev_free) { + malloc_printf("*** malloc[%d]: invariant broken for %p (2 free in a row)\n", getpid(), ptr); + return 0; + } + free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); + if (free_head->previous && !(small_meta_header(free_head->previous)[0] & SMALL_IS_FREE)) { + malloc_printf("*** malloc[%d]: invariant broken for %p (previous %p is not a free pointer)\n", getpid(), ptr, free_head->previous); + return 0; + } + if (free_head->next && !(small_meta_header(free_head->next)[0] & SMALL_IS_FREE)) { + malloc_printf("*** malloc[%d]: invariant broken for %p (next is not a free pointer)\n", getpid(), ptr); + return 0; } - } else { - // free pointer - msize_t msize = msize_and_free & ~THIS_FREE; - free_list_t *free_head = ptr; - msize_t *follower = (void *)FOLLOWING_PTR(ptr, msize); - if ((msize_and_free & PREV_FREE) && !prev_free) { - malloc_printf("*** malloc[%d]: invariant broken for free block %p this msize=%d: PREV_FREE set while previous block is in use\n", getpid(), ptr, msize); - return 0; + if (SMALL_PREVIOUS_MSIZE(follower) != msize) { + malloc_printf("*** malloc[%d]: invariant broken for small free %p followed by %p in region [%p-%p] (end marker incorrect) should be %d; in fact %d\n", getpid(), ptr, follower, SMALL_REGION_ADDRESS(*region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); + return 0; } - if (msize < MIN_BLOCK) { - malloc_printf("*** malloc[%d]: invariant broken for free block %p this msize=%d\n", getpid(), ptr, msize); - return 0; - } - if (prev_free) { - malloc_printf("*** malloc[%d]: invariant broken for %p (2 free in a row)\n", getpid(), ptr); - return 0; - } - free_list_checksum(szone, free_head); - if (free_head->previous && !(MSIZE_FLAGS_FOR_PTR(free_head->previous) & THIS_FREE)) { - malloc_printf("*** malloc[%d]: invariant broken for %p (previous %p is not a free pointer)\n", getpid(), ptr, free_head->previous); - return 0; - } - if (free_head->next && !(MSIZE_FLAGS_FOR_PTR(free_head->next) & THIS_FREE)) { - malloc_printf("*** malloc[%d]: invariant broken for %p (next is not a free pointer)\n", getpid(), ptr); - return 0; - } - if (PREVIOUS_MSIZE(follower) != msize) { - malloc_printf("*** malloc[%d]: invariant broken for free %p followed by %p in region [%x-%x] (end marker incorrect) should be %d; in fact %d\n", getpid(), ptr, follower, REGION_ADDRESS(*region), region_end, msize, PREVIOUS_MSIZE(follower)); - return 0; - } - ptr = follower; - prev_free = PREV_FREE; - } + ptr = follower; + prev_free = SMALL_IS_FREE; + } } return 1; } -static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned num_regions, memory_reader_t reader, vm_range_recorder_t recorder) { - region_t *regions; +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_region_t *regions; unsigned index = 0; vm_range_t buffer[MAX_RECORDER_BUFFER]; unsigned count = 0; kern_return_t err; - err = reader(task, region_address, sizeof(region_t) * num_regions, (void **)®ions); + err = reader(task, region_address, sizeof(small_region_t) * num_regions, (void **)®ions); if (err) return err; while (index < num_regions) { - region_t region = regions[index++]; - vm_range_t range = {REGION_ADDRESS(region), REGION_SIZE}; - vm_address_t start = range.address + QUANTUM; - // malloc_printf("Enumerating small ptrs for Region starting at 0x%x\n", start); - if (type_mask & MALLOC_PTR_REGION_RANGE_TYPE) recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &range, 1); - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) while (start < range.address + range.size) { - void *previous; - msize_t msize_and_free; - err = reader(task, start - PTR_HEADER_SIZE, QUANTUM, (void **)&previous); - if (err) return err; - previous += PTR_HEADER_SIZE; - msize_and_free = MSIZE_FLAGS_FOR_PTR(previous); - if (!(msize_and_free & THIS_FREE)) { - // Block in use - msize_t msize = msize_and_free & ~PREV_FREE; - if (!msize) break; // last encountered - buffer[count].address = start; - buffer[count].size = (msize << SHIFT_QUANTUM) - PTR_HEADER_SIZE; - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - start += msize << SHIFT_QUANTUM; - } else { - // free pointer - msize_t msize = msize_and_free & ~THIS_FREE; - start += msize << SHIFT_QUANTUM; - } - } - // malloc_printf("End region - count=%d\n", count); - } - if (count) recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + small_region_t region = regions[index]; + vm_range_t range = {SMALL_REGION_ADDRESS(region), SMALL_REGION_SIZE}; + // malloc_printf("Enumerating small ptrs for Region starting at %p\n", range.address); + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + vm_range_t admin_range = {range.address + (1 << SMALL_BLOCKS_ALIGN), 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)) { + vm_range_t ptr_range = {range.address, 1 << SMALL_BLOCKS_ALIGN}; + recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); + } + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + unsigned char *mapped_region; + err = reader(task, range.address, range.size, (void **)&mapped_region); + if (err) return err; + msize_t *block_header = (msize_t *)(mapped_region + (1 << SMALL_BLOCKS_ALIGN)); + unsigned block_index = 0; + unsigned block_limit = NUM_SMALL_BLOCKS; + if (index == num_regions - 1) + block_limit -= (small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM); + while (block_index < block_limit) { + msize_t msize_and_free = block_header[block_index]; + msize_t msize = msize_and_free & ~ SMALL_IS_FREE; + if (! (msize_and_free & SMALL_IS_FREE)) { + // Block in use + buffer[count].address = range.address + (block_index << SHIFT_SMALL_QUANTUM); + buffer[count].size = msize << SHIFT_SMALL_QUANTUM; + count++; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } + block_index += msize; + } + // malloc_printf("End small region - count=%d\n", count); + } + index++; + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + } return 0; } -static INLINE void *small_malloc_from_free_list(szone_t *szone, msize_t msize, boolean_t *locked) { +static INLINE void * +small_malloc_from_free_list(szone_t *szone, msize_t msize) { + // Assumes locked + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + 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 = szone->free_list + MAX_GRAIN - 1; + if (!bitmap) goto try_small_from_end; + grain = BITMAP32_FFS(bitmap) - 1; // first try the small grains - free_list = szone->free_list + grain_for_msize(szone, msize); + free_list_t **free_list; + free_list_t **limit = szone->small_free_list + NUM_SMALL_SLOTS - 1; + free_list = szone->small_free_list + grain; while (free_list < limit) { - // try bigger grains - ptr = *free_list; - if (ptr) { - if (!*locked) { *locked = 1; SZONE_LOCK(szone); CHECK(szone, __PRETTY_FUNCTION__); } - ptr = *free_list; - if (ptr) { - // optimistic test worked - free_list_t *next; - next = ((free_list_t *)ptr)->next; - if (next) { - next->previous = NULL; - free_list_set_checksum(szone, next); - } - *free_list = next; - this_msize = MSIZE_FLAGS_FOR_PTR(ptr) & ~THIS_FREE; - MSIZE_FLAGS_FOR_PTR(FOLLOWING_PTR(ptr, this_msize)) &= ~ PREV_FREE; - goto add_leftover_and_proceed; - } - } - free_list++; + // try bigger grains + ptr = *free_list; + if (ptr) { + free_list_t *next; + next = ((free_list_t *)ptr)->next; + if (next) { + next->previous = NULL; + free_list_set_checksum(szone, next); + } + *free_list = next; + this_msize = small_meta_header(ptr)[0] & ~ SMALL_IS_FREE; + // malloc_printf("small_malloc_from_free_list: allocated from free list\n"); + goto add_leftover_and_proceed; + } + free_list++; } // We now check the large grains for one that is big enough - if (!*locked) { *locked = 1; SZONE_LOCK(szone); CHECK(szone, __PRETTY_FUNCTION__); } ptr = *free_list; while (ptr) { - this_msize = MSIZE_FLAGS_FOR_PTR(ptr) & ~THIS_FREE; - if (this_msize >= msize) { - free_list_remove_ptr(szone, ptr, this_msize); - goto add_leftover_and_proceed; - } - ptr = ((free_list_t *)ptr)->next; + this_msize = small_meta_header(ptr)[0] & ~ SMALL_IS_FREE; + if (this_msize >= msize) { + // malloc_printf("small_malloc_from_free_list: allocated from last free list\n"); + small_free_list_remove_ptr(szone, ptr, this_msize); + goto add_leftover_and_proceed; + } + ptr = ((free_list_t *)ptr)->next; + } +try_small_from_end: + // Let's see if we can use szone->small_bytes_free_at_end + // malloc_printf("Found nothing in free list small_bytes_free_at_end=%y\n", szone-> small_bytes_free_at_end); + if (szone->small_bytes_free_at_end >= (msize << SHIFT_SMALL_QUANTUM)) { + 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 -= msize << SHIFT_SMALL_QUANTUM; + if (szone->small_bytes_free_at_end) { + // let's mark this block as in use to serve as boundary + small_meta_header(ptr + (msize << SHIFT_SMALL_QUANTUM))[0] = szone->small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM; + } + this_msize = msize; + goto return_small_alloc; } return NULL; add_leftover_and_proceed: - if (this_msize >= msize + MIN_BLOCK) { - if (LOG(szone,ptr)) malloc_printf("In small_malloc_should_clear(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - free_list_add_ptr(szone, ptr + (msize << SHIFT_QUANTUM), this_msize - msize); - this_msize = msize; + if (this_msize > msize) { + msize_t leftover_msize = this_msize - msize; + void *leftover_ptr = ptr + (msize << SHIFT_SMALL_QUANTUM); +#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); + } +#endif + small_free_list_add_ptr(szone, leftover_ptr, leftover_msize); + msize_t *meta_headers = small_meta_headers(leftover_ptr); + msize_t leftover_index = small_meta_index(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 += this_msize << SHIFT_QUANTUM; + szone->num_bytes_in_small_objects += this_msize << SHIFT_SMALL_QUANTUM; #if DEBUG_MALLOC - if (LOG(szone,ptr)) malloc_printf("In small_malloc_should_clear(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); + if (LOG(szone,ptr)) { + malloc_printf("In small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); + } #endif - MSIZE_FLAGS_FOR_PTR(ptr) = this_msize; + small_meta_header(ptr)[0] = this_msize; return ptr; } -static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) { +static INLINE void * +small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) { boolean_t locked = 0; void *ptr; -#if DEBUG_MALLOC - if (! (msize & 0xffff)) { - szone_error(szone, "Invariant broken (!msize) in allocation (region)", NULL); - } - if (msize < MIN_BLOCK) { - szone_error(szone, "Invariant broken (msize too small) in allocation (region)", NULL); +#if SMALL_CACHE + ptr = (void *)szone->last_small_free; + if ((((unsigned)ptr) & (SMALL_QUANTUM - 1)) == msize) { + // we have a candidate - let's lock to make sure + LOCK_AND_NOTE_LOCKED(szone, locked); + if (ptr == (void *)szone->last_small_free) { + szone->last_small_free = NULL; + // malloc_printf("using last_small_free\n"); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + ptr = (void *)((unsigned)ptr & ~ (SMALL_QUANTUM - 1)); + if (cleared_requested) { + memset(ptr, 0, msize << SHIFT_SMALL_QUANTUM); + } + return ptr; + } + // malloc_printf("optimistic locking for last_small_free failed\n"); } #endif - ptr = small_malloc_from_free_list(szone, msize, &locked); + // Except in rare occasions where we need to add a new region, we are going to end up locking, so we might as well lock right away to avoid doing unnecessary optimistic probes + if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked); + ptr = small_malloc_from_free_list(szone, msize); if (ptr) { - CHECK(szone, __PRETTY_FUNCTION__); - SZONE_UNLOCK(szone); - if (cleared_requested) memset(ptr, 0, (msize << SHIFT_QUANTUM) - PTR_HEADER_SIZE); - return ptr; - } else { - if (!locked) SZONE_LOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = small_malloc_from_region_no_lock(szone, msize); - // we don't clear because this freshly allocated space is pristine - CHECK(szone, __PRETTY_FUNCTION__); - SZONE_UNLOCK(szone); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, msize << SHIFT_SMALL_QUANTUM); + } + return ptr; } + ptr = small_malloc_from_region_no_lock(szone, msize); + // we don't clear because this freshly allocated space is pristine + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); return ptr; } -static INLINE void *small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) { +static INLINE void * +small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) { // tries to allocate a small, cleared block - boolean_t locked = 1; + // Assumes already locked + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); void *ptr; - ptr = small_malloc_from_free_list(szone, msize, &locked); + ptr = small_malloc_from_free_list(szone, msize); if (ptr) { - memset(ptr, 0, (msize << SHIFT_QUANTUM) - PTR_HEADER_SIZE); - return ptr; + memset(ptr, 0, msize << SHIFT_SMALL_QUANTUM); + return ptr; } else { - ptr = small_malloc_from_region_no_lock(szone, msize); - // we don't clear because this freshly allocated space is pristine + ptr = small_malloc_from_region_no_lock(szone, msize); + // we don't clear because this freshly allocated space is pristine } return ptr; } +static INLINE void +free_small(szone_t *szone, void *ptr, small_region_t *small_region) { + // ptr is known to be in small_region + msize_t msize_and_free; + msize_and_free = small_meta_header(ptr)[0]; + if (msize_and_free & SMALL_IS_FREE) { + szone_error(szone, "Object already freed being freed", ptr); + return; + } + CHECK(szone, __PRETTY_FUNCTION__); + // malloc_printf("%p[%x]\n", ptr, msize_and_free); + SZONE_LOCK(szone); +#if SMALL_CACHE + void *ptr2 = szone->last_small_free; + szone->last_small_free = (void *)(((unsigned)ptr) | msize_and_free); + if (!ptr2) { + // malloc_printf("stuffing last_small_free\n"); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + return; + } + // malloc_printf("replacing previous last_small_free %p with %p\n", ptr2, szone->last_small_free); + msize_and_free = (unsigned)ptr2 & (SMALL_QUANTUM - 1); + ptr = (void *)(((unsigned)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); + } +#endif + small_free_no_lock(szone, small_region, ptr, msize_and_free); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); +} + +static void +print_small_free_list(szone_t *szone) { + grain_t grain = 0; + malloc_printf("Small free sizes: "); + while (grain < NUM_SMALL_SLOTS) { + free_list_t *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)); + } + grain++; + } + malloc_printf("\n"); +} + +static void +print_small_region(szone_t *szone, boolean_t verbose, small_region_t *region, size_t bytes_at_end) { + unsigned counts[1024]; + unsigned in_use = 0; + vm_address_t start = SMALL_REGION_ADDRESS(*region); + vm_address_t limit = SMALL_REGION_END(*region) - bytes_at_end; + memset(counts, 0, 1024 * sizeof(unsigned)); + while (start < limit) { + msize_t msize_and_free = small_meta_header((void *)start)[0]; + msize_t msize = msize_and_free & ~ SMALL_IS_FREE; + if (!(msize_and_free & SMALL_IS_FREE)) { + // block in use + if (msize < 1024) counts[msize]++; + in_use++; + } + start += msize << SHIFT_SMALL_QUANTUM; + } + 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) { + unsigned ci = 0; + malloc_printf("\n\tSizes in use: "); + while (ci < 1024) { + if (counts[ci]) { + malloc_printf("%d[%d] ", ci << SHIFT_SMALL_QUANTUM, counts[ci]); + } + ci++; + } + } + malloc_printf("\n"); +} + +static boolean_t +small_free_list_check(szone_t *szone, grain_t grain) { + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + unsigned count = 0; + free_list_t *ptr = szone->small_free_list[grain]; + free_list_t *previous = NULL; + while (ptr) { + msize_t msize_and_free = small_meta_header(ptr)[0]; + count++; + if (!(msize_and_free & SMALL_IS_FREE)) { + malloc_printf("*** malloc[%d]: In-use ptr in free list grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); + return 0; + } + if (((unsigned)ptr) & (SMALL_QUANTUM - 1)) { + malloc_printf("*** malloc[%d]: Unaligned ptr in free list grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); + return 0; + } + if (!small_region_for_ptr_no_lock(szone, ptr)) { + malloc_printf("*** malloc[%d]: Ptr not in szone grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); + return 0; + } + free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); + if (ptr->previous != previous) { + malloc_printf("*** malloc[%d]: Previous incorrectly set grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr); + return 0; + } + previous = ptr; + ptr = ptr->next; + } + return 1; +} + /********************* LARGE ENTRY UTILITIES ************************/ #if DEBUG_MALLOC -static void large_debug_print(szone_t *szone) { +static void +large_debug_print(szone_t *szone) { unsigned num_large_entries = szone->num_large_entries; unsigned index = num_large_entries; while (index--) { - large_entry_t *range = szone->large_entries + index; - large_entry_t entry = *range; - if (!LARGE_ENTRY_IS_EMPTY(entry)) malloc_printf("%d: 0x%x(%dKB); ", index, LARGE_ENTRY_ADDRESS(entry), LARGE_ENTRY_SIZE(entry)/1024); + large_entry_t *range = szone->large_entries + index; + large_entry_t entry = *range; + if (!LARGE_ENTRY_IS_EMPTY(entry)) { + malloc_printf("%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(entry), LARGE_ENTRY_SIZE(entry)); + } } malloc_printf("\n"); } #endif -static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) { +static large_entry_t * +large_entry_for_pointer_no_lock(szone_t *szone, + const void *ptr) { // result only valid during a lock unsigned num_large_entries = szone->num_large_entries; unsigned hash_index; @@ -779,87 +1971,112 @@ static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void hash_index = ((unsigned)ptr >> vm_page_shift) % num_large_entries; index = hash_index; do { - large_entry_t *range = szone->large_entries + index; - large_entry_t entry = *range; - if (LARGE_ENTRY_MATCHES(entry, ptr)) return range; - if (LARGE_ENTRY_IS_EMPTY(entry)) return NULL; // end of chain - index++; if (index == num_large_entries) index = 0; + large_entry_t *range = szone->large_entries + index; + large_entry_t entry = *range; + if (LARGE_ENTRY_MATCHES(entry, ptr)) return range; + if (LARGE_ENTRY_IS_EMPTY(entry)) return NULL; // end of chain + index++; if (index == num_large_entries) index = 0; } while (index != hash_index); return NULL; } -static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range) { +static void +large_entry_insert_no_lock(szone_t *szone, large_entry_t range) { unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = (range.address_and_num_pages >> vm_page_shift) % num_large_entries; + unsigned hash_index = (range.address_and_num_pages >> vm_page_shift) + % num_large_entries; unsigned index = hash_index; - // malloc_printf("Before insertion of 0x%x\n", LARGE_ENTRY_ADDRESS(range)); +// malloc_printf("Before insertion of %p\n", LARGE_ENTRY_ADDRESS(range)); do { - large_entry_t *entry = szone->large_entries + index; - if (LARGE_ENTRY_IS_EMPTY(*entry)) { - *entry = range; - return; // end of chain - } - index++; if (index == num_large_entries) index = 0; + large_entry_t *entry = szone->large_entries + index; + if (LARGE_ENTRY_IS_EMPTY(*entry)) { + *entry = range; + return; // end of chain + } + index++; if (index == num_large_entries) index = 0; } while (index != hash_index); } -static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) { +static INLINE void +large_entries_rehash_after_entry_no_lock(szone_t *szone, + large_entry_t *entry) { unsigned num_large_entries = szone->num_large_entries; unsigned hash_index = entry - szone->large_entries; unsigned index = hash_index; do { - large_entry_t range; - index++; if (index == num_large_entries) index = 0; - range = szone->large_entries[index]; - if (LARGE_ENTRY_IS_EMPTY(range)) return; - szone->large_entries[index].address_and_num_pages = 0; - large_entry_insert_no_lock(szone, range); // this will reinsert in the proper place + large_entry_t range; + index++; if (index == num_large_entries) index = 0; + range = szone->large_entries[index]; + if (LARGE_ENTRY_IS_EMPTY(range)) return; + szone->large_entries[index].address_and_num_pages = 0; + large_entry_insert_no_lock(szone, range); // this will reinsert in the + // proper place } while (index != hash_index); } -static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) { +static INLINE large_entry_t * +large_entries_alloc_no_lock(szone_t *szone, + unsigned num) { size_t size = num * sizeof(large_entry_t); boolean_t is_vm_allocation = size >= LARGE_THRESHOLD; if (is_vm_allocation) { - return (void *)allocate_pages(szone, round_page(size), 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE)); + // 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)); } else { - return small_malloc_cleared_no_lock(szone, (size + PTR_HEADER_SIZE + QUANTUM - 1) >> SHIFT_QUANTUM); + return small_malloc_cleared_no_lock(szone, (size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM); } } -static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num) { +static void +large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate) { + // returns range to deallocate size_t size = num * sizeof(large_entry_t); boolean_t is_vm_allocation = size >= LARGE_THRESHOLD; + // malloc_printf("In large_entries_free_no_lock %d %d\n", num, is_vm_allocation); if (is_vm_allocation) { - deallocate_pages(szone, (vm_address_t)entries, round_page(size), 0); + range_to_deallocate->address = (vm_address_t)entries; + range_to_deallocate->size = round_page(size); } else { - region_t *region = region_for_ptr_no_lock(szone, entries); - msize_t msize_and_free = MSIZE_FLAGS_FOR_PTR(entries); - if (msize_and_free & THIS_FREE) { - szone_error(szone, "Object already freed being freed", entries); - return; - } - small_free_no_lock(szone, region, entries, msize_and_free); + range_to_deallocate->size = 0; + small_region_t *region = small_region_for_ptr_no_lock(szone, entries); + msize_t msize_and_free = small_meta_header(entries)[0]; + if (msize_and_free & SMALL_IS_FREE) { + szone_error(szone, "Object already freed being freed", entries); + return; + } + small_free_no_lock(szone, region, entries, msize_and_free); } } -static void large_entries_grow_no_lock(szone_t *szone) { +static void +large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) { + // sets range_to_deallocate unsigned old_num_entries = szone->num_large_entries; large_entry_t *old_entries = szone->large_entries; - unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 : 15; // always an odd number for good hashing + unsigned new_num_entries = (old_num_entries) ? old_num_entries + * 2 + 1 : 63; // always an odd number for good hashing large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries); unsigned index = old_num_entries; szone->num_large_entries = new_num_entries; szone->large_entries = new_entries; - // malloc_printf("_grow_large_entries old_num_entries=%d new_num_entries=%d\n", old_num_entries, new_num_entries); + // malloc_printf("_grow_large_entries old_num_entries=%d new_num_entries=%d %p\n", old_num_entries, new_num_entries, old_entries); while (index--) { - large_entry_t oldRange = old_entries[index]; - if (!LARGE_ENTRY_IS_EMPTY(oldRange)) large_entry_insert_no_lock(szone, oldRange); + large_entry_t oldRange = old_entries[index]; + if (!LARGE_ENTRY_IS_EMPTY(oldRange)) { + large_entry_insert_no_lock(szone, oldRange); + } + } + if (old_entries) { + large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate); + } else { + range_to_deallocate->size = 0; } - if (old_entries) large_entries_free_no_lock(szone, old_entries, old_num_entries); } -static vm_range_t large_free_no_lock(szone_t *szone, large_entry_t *entry) { +static vm_range_t +large_free_no_lock(szone_t *szone, large_entry_t *entry) { // frees the specific entry in the size table // returns a range to truly deallocate vm_range_t range; @@ -868,123 +2085,218 @@ static vm_range_t 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, range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags); - range.address -= vm_page_size; - range.size += 2 * vm_page_size; - } - // printf("Entry is 0x%x=%d; cache is 0x%x ; found=0x%x\n", entry, entry-szone->large_entries, szone->large_entries, large_entry_for_pointer_no_lock(szone, (void *)range.address)); + protect(szone, range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, + szone->debug_flags); + range.address -= 1 << vm_page_shift; + range.size += 2 * (1 << vm_page_shift); + } +// malloc_printf("Entry is %p=%d; cache is %p ; found=%p\n", entry, +// entry-szone->large_entries, szone->large_entries, +// large_entry_for_pointer_no_lock(szone, (void *)range.address)); entry->address_and_num_pages = 0; large_entries_rehash_after_entry_no_lock(szone, entry); #if DEBUG_MALLOC if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) { - malloc_printf("*** malloc[%d]: Freed entry 0x%x still in use; num_large_entries=%d\n", getpid(), range.address, szone->num_large_entries); - large_debug_print(szone); - sleep(3600); + malloc_printf("*** malloc[%d]: Freed entry %p still in use; " + "num_large_entries=%d\n", getpid(), range.address, + szone->num_large_entries); + large_debug_print(szone); + szone_sleep(); } #endif return range; } -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 INLINE boolean_t +try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { + // returns 1 on success + msize_t *meta_headers = small_meta_headers(ptr); + msize_t index = small_meta_index(ptr); + msize_t old_msize = old_size >> SHIFT_SMALL_QUANTUM; + msize_t new_msize = (new_size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM; + void *next_block = (char *)ptr + old_size; + msize_t next_index = index + old_msize; + if (next_index >= NUM_SMALL_BLOCKS) { + // malloc_printf("try_realloc_small_in_place can't take place at end %p %d %d %d\n", ptr, old_size, new_size, next_index); + return 0; + } +#if DEBUG_MALLOC + if ((vm_address_t)next_block & (SMALL_QUANTUM - 1)) { + szone_error(szone, "Internal invariant broken in realloc(next_block)", next_block); + } + if (meta_headers[index] != old_msize) malloc_printf("*** try_realloc_small_in_place incorrect old %d %d\n", meta_headers[index], old_msize); +#endif + SZONE_LOCK(szone); + // If the next block is free, we coalesce + msize_t next_msize_and_free; + msize_t next_msize; + next_msize_and_free = meta_headers[next_index]; + next_msize = next_msize_and_free & ~ SMALL_IS_FREE; + if (!(next_msize_and_free & SMALL_IS_FREE) || (old_msize + next_msize < new_msize)) { + SZONE_UNLOCK(szone); + return 0; + } + // malloc_printf("Small realloc in place for %p; current msize=%db(%d) next=%p next_msize=%d wanted=%db(%d)\n", ptr, old_size, meta_headers[index], next_block, next_msize, new_size, new_msize); + small_free_list_remove_ptr(szone, next_block, next_msize); + small_meta_header_set_middle(meta_headers, next_index); + msize_t leftover_msize = old_msize + next_msize - new_msize; + if (leftover_msize) { + void *leftover = ptr + (new_msize << SHIFT_SMALL_QUANTUM); + // malloc_printf("Leftover in realloc in place %p msize=%d\n", leftover, leftover_msize); + small_free_list_add_ptr(szone, leftover, leftover_msize); + msize_t leftover_index = index + new_msize; + small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize); + } +#if DEBUG_MALLOC + if ((new_msize << SHIFT_SMALL_QUANTUM) >= LARGE_THRESHOLD) { + malloc_printf("*** Realloc in place for %p exceeded msize=%d\n", new_msize); + } +#endif + small_meta_header_set_in_use(meta_headers, index, new_msize); +#if DEBUG_MALLOC + if (LOG(szone,ptr)) { + malloc_printf("In szone_realloc(), ptr=%p, msize=%d\n", ptr, small_meta_header(ptr)[0]); + } +#endif + szone->num_bytes_in_small_objects += (new_msize - old_msize) << SHIFT_SMALL_QUANTUM; + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); +// malloc_printf("Extended ptr %p for realloc old=%d desired=%d new=%d " +// "leftover=%d\n", ptr, (unsigned)old_size, (unsigned)new_size, +// (unsigned)szone_size(szone, ptr), leftover_msize << SHIFT_SMALL_QUANTUM); + return 1; +} + +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) { unsigned index = 0; vm_range_t buffer[MAX_RECORDER_BUFFER]; unsigned count = 0; large_entry_t *entries; kern_return_t err; - err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries); + err = reader(task, large_entries_address, + sizeof(large_entry_t) * num_entries, (void **)&entries); if (err) return err; index = num_entries; - if ((type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) && (num_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD)) { - vm_range_t range; - range.address = large_entries_address; - range.size = round_page(num_entries * sizeof(large_entry_t)); - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1); - } - if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE)) while (index--) { - large_entry_t entry = entries[index]; - if (!LARGE_ENTRY_IS_EMPTY(entry)) { - vm_range_t range; - range.address = LARGE_ENTRY_ADDRESS(entry); - range.size = LARGE_ENTRY_SIZE(entry); - buffer[count++] = range; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); - count = 0; - } - } - } - if (count) recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); + if ((type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) + && (num_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD)) { + vm_range_t range; + range.address = large_entries_address; + range.size = round_page(num_entries * sizeof(large_entry_t)); + recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1); + } + if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE + | MALLOC_PTR_REGION_RANGE_TYPE)) + while (index--) { + large_entry_t entry = entries[index]; + if (!LARGE_ENTRY_IS_EMPTY(entry)) { + vm_range_t range; + range.address = LARGE_ENTRY_ADDRESS(entry); + range.size = LARGE_ENTRY_SIZE(entry); + buffer[count++] = range; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE + | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); + count = 0; + } + } + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE + | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); + } return 0; } /********************* HUGE ENTRY UTILITIES ************************/ -static huge_entry_t *huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) { +static huge_entry_t * +huge_entry_for_pointer_no_lock(szone_t *szone, + const void *ptr) { unsigned index = szone->num_huge_entries; while (index--) { - huge_entry_t *huge = szone->huge_entries + index; - if (huge->address == (vm_address_t)ptr) return huge; + huge_entry_t *huge = szone->huge_entries + index; + if (huge->address == (vm_address_t)ptr) return huge; } return NULL; } -static boolean_t huge_entry_append(szone_t *szone, huge_entry_t huge) { - // We do a little dance with locking because doing allocation (even in the default szone) may cause something to get freed in this szone, with a deadlock +static boolean_t +huge_entry_append(szone_t *szone, huge_entry_t huge) { + // We do a little dance with locking because doing allocation (even in the + // default szone) may cause something to get freed in this szone, with a + // deadlock + // Returns 1 on success huge_entry_t *new_huge_entries = NULL; SZONE_LOCK(szone); while (1) { - unsigned num_huge_entries; - num_huge_entries = szone->num_huge_entries; - SZONE_UNLOCK(szone); - // malloc_printf("In huge_entry_append currentEntries=%d\n", num_huge_entries); - if (new_huge_entries) szone_free(szone, new_huge_entries); - new_huge_entries = szone_malloc(szone, (num_huge_entries + 1) * sizeof(huge_entry_t)); - if (new_huge_entries == NULL) + unsigned num_huge_entries; + num_huge_entries = szone->num_huge_entries; + SZONE_UNLOCK(szone); +// malloc_printf("In huge_entry_append currentEntries=%d\n", num_huge_entries); + if (new_huge_entries) szone_free(szone, new_huge_entries); + new_huge_entries = szone_malloc(szone, (num_huge_entries + 1) * sizeof(huge_entry_t)); + if (new_huge_entries == NULL) return 0; + SZONE_LOCK(szone); + if (num_huge_entries == szone->num_huge_entries) { + // No change - our malloc still applies + huge_entry_t *old_huge_entries = szone->huge_entries; + if (num_huge_entries) { + memcpy(new_huge_entries, old_huge_entries, num_huge_entries * sizeof(huge_entry_t)); + } + new_huge_entries[szone->num_huge_entries++] = huge; + szone->huge_entries = new_huge_entries; + SZONE_UNLOCK(szone); + szone_free(szone, old_huge_entries); +// malloc_printf("Done huge_entry_append now=%d\n", szone->num_huge_entries); return 1; - SZONE_LOCK(szone); - if (num_huge_entries == szone->num_huge_entries) { - // No change - our malloc still applies - huge_entry_t *old_huge_entries = szone->huge_entries; - if (num_huge_entries) memcpy(new_huge_entries, old_huge_entries, num_huge_entries * sizeof(huge_entry_t)); - new_huge_entries[szone->num_huge_entries++] = huge; - szone->huge_entries = new_huge_entries; - SZONE_UNLOCK(szone); - szone_free(szone, old_huge_entries); - // malloc_printf("Done huge_entry_append now=%d\n", szone->num_huge_entries); - return 0; - } - // try again! - } -} - -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) { + } + // try again! + } +} + +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) { huge_entry_t *entries; kern_return_t err; - err = reader(task, huge_entries_address, sizeof(huge_entry_t) * num_entries, (void **)&entries); + err = reader(task, huge_entries_address, sizeof(huge_entry_t) * num_entries, + (void **)&entries); if (err) return err; - if (num_entries) recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, entries, num_entries); + if (num_entries) { + recorder(task, context, + MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, entries, + num_entries); + } return 0; } -static void *large_and_huge_malloc(szone_t *szone, unsigned num_pages) { +static void * +large_and_huge_malloc(szone_t *szone, unsigned num_pages) { vm_address_t addr = 0; + vm_range_t range_to_deallocate; if (!num_pages) num_pages = 1; // minimal allocation size for this szone - // malloc_printf("In large_and_huge_malloc for %dKB\n", num_pages * vm_page_size / 1024); +// malloc_printf("In large_and_huge_malloc for %y\n", num_pages * (1 << vm_page_shift)); + range_to_deallocate.size = 0; if (num_pages >= (1 << vm_page_shift)) { - huge_entry_t huge; - huge.size = num_pages << vm_page_shift; - addr = allocate_pages(szone, huge.size, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_HUGE)); - if (!addr) return NULL; - huge.address = addr; - if (huge_entry_append(szone, huge)) - return NULL; - SZONE_LOCK(szone); - szone->num_bytes_in_huge_objects += huge.size; + huge_entry_t huge; + huge.size = num_pages << vm_page_shift; + addr = allocate_pages(szone, huge.size, 0, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_HUGE)); + if (!addr) return NULL; + huge.address = addr; + if (! huge_entry_append(szone, huge)) return NULL; + SZONE_LOCK(szone); + szone->num_bytes_in_huge_objects += huge.size; } else { - vm_size_t size = num_pages << vm_page_shift; - large_entry_t entry; - addr = allocate_pages(szone, size, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE)); - if (LOG(szone, addr)) malloc_printf("In szone_malloc true large allocation at %p for %dKB\n", (void *)addr, size / 1024); + vm_size_t size = num_pages << vm_page_shift; + large_entry_t entry; + addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MAKE_TAG(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); +#endif SZONE_LOCK(szone); if (!addr) { SZONE_UNLOCK(szone); @@ -992,384 +2304,512 @@ static void *large_and_huge_malloc(szone_t *szone, unsigned num_pages) { } #if DEBUG_MALLOC if (large_entry_for_pointer_no_lock(szone, (void *)addr)) { - malloc_printf("Freshly allocated is already in use: 0x%x\n", addr); + malloc_printf("Freshly allocated is already in use: %p\n", addr); large_debug_print(szone); - sleep(3600); + szone_sleep(); } #endif - 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 - // malloc_printf("In szone_malloc growing hash table current=%d\n", szone->num_large_entries); - large_entries_grow_no_lock(szone); - } - // malloc_printf("Inserting large entry (0x%x, %dKB)\n", addr, num_pages * vm_page_size / 1024); - entry.address_and_num_pages = addr | 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 + // malloc_printf("In szone_malloc growing hash table current=%d\n", szone->num_large_entries); + large_entries_grow_no_lock(szone, &range_to_deallocate); + } +// malloc_printf("Inserting large entry (%p, %y)\n", addr, num_pages * (1 << vm_page_shift)); + entry.address_and_num_pages = addr | num_pages; #if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, (void *)addr)) { - malloc_printf("Entry about to be added already in use: 0x%x\n", addr); - large_debug_print(szone); - sleep(3600); - } + if (large_entry_for_pointer_no_lock(szone, (void *)addr)) { + malloc_printf("Entry about to be added already in use: %p\n", + addr); + large_debug_print(szone); + szone_sleep(); + } #endif - large_entry_insert_no_lock(szone, entry); + large_entry_insert_no_lock(szone, entry); #if DEBUG_MALLOC - if (!large_entry_for_pointer_no_lock(szone, (void *)addr)) { - malloc_printf("Can't find entry just added\n"); - large_debug_print(szone); - sleep(3600); - } + if (!large_entry_for_pointer_no_lock(szone, (void *)addr)) { + malloc_printf("Can't find entry just added\n"); + large_debug_print(szone); + szone_sleep(); + } #endif - // malloc_printf("Inserted large entry (0x%x, %d pages)\n", addr, num_pages); - szone->num_large_objects_in_use ++; - szone->num_bytes_in_large_objects += size; +// malloc_printf("Inserted large entry (%p, %d pages)\n", addr, +// num_pages); + szone->num_large_objects_in_use ++; + szone->num_bytes_in_large_objects += size; } SZONE_UNLOCK(szone); + if (range_to_deallocate.size) { + deallocate_pages(szone, range_to_deallocate.address, range_to_deallocate.size, 0); // we deallocate outside the lock + // malloc_printf("Deallocated large entries %d\n", range_to_deallocate.size); + } return (void *)addr; } -/********************* Zone call backs ************************/ - -static void szone_free(szone_t *szone, void *ptr) { - region_t *region; +static INLINE void +free_large_or_huge(szone_t *szone, void *ptr) { + // We have established ptr is page-aligned and not tiny nor small large_entry_t *entry; vm_range_t vm_range_to_deallocate; huge_entry_t *huge; - if (LOG(szone, ptr)) malloc_printf("In szone_free with %p\n", ptr); - if (!ptr) return; - if ((vm_address_t)ptr & (QUANTUM - 1)) { - szone_error(szone, "Non-aligned pointer being freed", ptr); - return; - } - // try a small pointer - region = region_for_ptr_no_lock(szone, ptr); - if (region) { - // this is indeed a valid pointer - msize_t msize_and_free; - SZONE_LOCK(szone); - msize_and_free = MSIZE_FLAGS_FOR_PTR(ptr); - if (msize_and_free & THIS_FREE) { - szone_error(szone, "Object already freed being freed", ptr); - return; - } - CHECK(szone, __PRETTY_FUNCTION__); - small_free_no_lock(szone, region, ptr, msize_and_free); - CHECK(szone, __PRETTY_FUNCTION__); - SZONE_UNLOCK(szone); - return; - } - if (((unsigned)ptr) & (vm_page_size - 1)) { - szone_error(szone, "Non-page-aligned, non-allocated pointer being freed", ptr); - return; - } SZONE_LOCK(szone); entry = large_entry_for_pointer_no_lock(szone, ptr); if (entry) { - // malloc_printf("Ready for deallocation [0x%x-%dKB]\n", LARGE_ENTRY_ADDRESS(*entry), LARGE_ENTRY_SIZE(*entry)/1024); - if (KILL_THRESHOLD && (LARGE_ENTRY_SIZE(*entry) > KILL_THRESHOLD)) { - // We indicate to the VM system that these pages contain garbage and therefore don't need to be swapped out - vm_msync(mach_task_self(), LARGE_ENTRY_ADDRESS(*entry), LARGE_ENTRY_SIZE(*entry), VM_SYNC_KILLPAGES); - } - vm_range_to_deallocate = large_free_no_lock(szone, entry); +// malloc_printf("Ready for deallocation [%p-%y]\n", LARGE_ENTRY_ADDRESS(*entry), LARGE_ENTRY_SIZE(*entry)); + vm_range_to_deallocate = large_free_no_lock(szone, entry); #if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, ptr)) { - malloc_printf("*** malloc[%d]: Just after freeing 0x%x still in use num_large_entries=%d\n", getpid(), ptr, szone->num_large_entries); - large_debug_print(szone); - sleep(3600); - } + if (large_entry_for_pointer_no_lock(szone, ptr)) { + malloc_printf("*** malloc[%d]: Just after freeing %p still in use num_large_entries=%d\n", getpid(), ptr, szone->num_large_entries); + large_debug_print(szone); + szone_sleep(); + } #endif } else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) { - vm_range_to_deallocate = *huge; - *huge = szone->huge_entries[--szone->num_huge_entries]; // last entry fills that spot - szone->num_bytes_in_huge_objects -= vm_range_to_deallocate.size; + vm_range_to_deallocate = *huge; + *huge = szone->huge_entries[--szone->num_huge_entries]; // last entry fills that spot + szone->num_bytes_in_huge_objects -= vm_range_to_deallocate.size; } else { #if DEBUG_MALLOC - large_debug_print(szone); + large_debug_print(szone); #endif - szone_error(szone, "Pointer being freed was not allocated", ptr); - return; + szone_error(szone, "Pointer being freed was not allocated", ptr); + return; } - CHECK(szone, __PRETTY_FUNCTION__); SZONE_UNLOCK(szone); // we release the lock asap + CHECK(szone, __PRETTY_FUNCTION__); // we deallocate_pages, including guard pages if (vm_range_to_deallocate.address) { - // malloc_printf("About to deallocate 0x%x size %dKB\n", vm_range_to_deallocate.address, vm_range_to_deallocate.size / 1024); +// malloc_printf("About to deallocate %p size %y\n", vm_range_to_deallocate.address, vm_range_to_deallocate.size); +#if DEBUG_MALLOC + if (large_entry_for_pointer_no_lock(szone, + (void *)vm_range_to_deallocate.address)) { + malloc_printf("*** malloc[%d]: Invariant broken: %p still in use num_large_entries=%d\n", getpid(), vm_range_to_deallocate.address, szone->num_large_entries); + large_debug_print(szone); + szone_sleep(); + } +#endif + deallocate_pages(szone, vm_range_to_deallocate.address, vm_range_to_deallocate.size, 0); + } +} + +static INLINE int +try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { + vm_address_t addr = (vm_address_t)ptr + old_size; + large_entry_t *entry; + kern_return_t err; #if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) { - malloc_printf("*** malloc[%d]: Invariant broken: 0x%x still in use num_large_entries=%d\n", getpid(), vm_range_to_deallocate.address, szone->num_large_entries); - large_debug_print(szone); - sleep(3600); - } + if (old_size != ((old_size >> vm_page_shift) << vm_page_shift)) { + malloc_printf("*** old_size is %d\n", old_size); + } #endif - deallocate_pages(szone, vm_range_to_deallocate.address, vm_range_to_deallocate.size, 0); +// malloc_printf("=== Trying (1) to extend %p from %d to %d\n", ptr, old_size, new_size); + SZONE_LOCK(szone); + entry = large_entry_for_pointer_no_lock(szone, (void *)addr); + SZONE_UNLOCK(szone); + if (entry) { + return 0; // large pointer already exist in table - extension is not going to work + } + new_size = round_page(new_size); +// malloc_printf("=== Trying (2) to extend %p from %d to %d\n", ptr, old_size, new_size); + /* + * Ask for allocation at a specific address, and mark as realloc + * to request coalescing with previous realloc'ed extensions. + */ + err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC)); + if (err != KERN_SUCCESS) { + return 0; + } + SZONE_LOCK(szone); + /* + * If the new size is still under the large/huge threshold, we can just + * extend the existing large block. + * + * Note: this logic is predicated on the understanding that an allocated + * block can never really shrink, so that the new size will always be + * larger than the old size. + */ + if ((new_size >> vm_page_shift) < (1 << vm_page_shift)) { + /* extend existing large entry */ + entry = large_entry_for_pointer_no_lock(szone, ptr); + if (!entry) { + szone_error(szone, "large entry reallocated is not properly in table", ptr); + /* XXX will cause fault on next reference to entry */ + } + entry->address_and_num_pages = (vm_address_t)ptr | (new_size >> vm_page_shift); + szone->num_bytes_in_large_objects += new_size - old_size; + } else if ((old_size >> vm_page_shift) >= (1 << vm_page_shift)) { + /* extend existing huge entry */ + huge_entry_t *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); + /* XXX will cause fault on next reference to huge_entry */ + } + huge_entry->size = new_size; + szone->num_bytes_in_huge_objects += new_size - old_size; + } else { + /* need to convert large entry to huge entry */ + huge_entry_t huge; + + /* release large entry, note we still have the VM allocation */ + entry = large_entry_for_pointer_no_lock(szone, ptr); + large_entry_t saved_entry = *entry; // in case we need to put it back + large_free_no_lock(szone, entry); + szone->num_bytes_in_large_objects -= old_size; + + /* and get a huge entry */ + huge.address = (vm_address_t)ptr; + huge.size = new_size; /* fix up size */ + SZONE_UNLOCK(szone); + if (huge_entry_append(szone, huge)) { + szone->num_bytes_in_huge_objects += new_size; + return 1; // success! + } + SZONE_LOCK(szone); + // we leak memory (the extra space appended) but data structures are correct + large_entry_insert_no_lock(szone, saved_entry); // this will reinsert the large entry } +// malloc_printf("=== Successfully reallocated at end of %p from %d to %d\n", ptr, old_size, new_size); + SZONE_UNLOCK(szone); // we release the lock asap + return 1; } -static INLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) { - void *ptr; - if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) { - // think small - size_t msize = (size + PTR_HEADER_SIZE + QUANTUM - 1) >> SHIFT_QUANTUM; - if (msize < MIN_BLOCK) msize = MIN_BLOCK; - ptr = small_malloc_should_clear(szone, msize, cleared_requested); +/********************* Zone call backs ************************/ + +static void +szone_free(szone_t *szone, void *ptr) { + // malloc_printf("szone_free(%p)\n", ptr); #if DEBUG_MALLOC - if ((MSIZE_FLAGS_FOR_PTR(ptr) & ~ PREV_FREE) < msize) { - malloc_printf("ptr=%p this=%d msize=%d\n", ptr, MSIZE_FLAGS_FOR_PTR(ptr), (int)msize); - szone_error(szone, "Pointer allocated has improper size (1)", ptr); - return NULL; - } - if ((MSIZE_FLAGS_FOR_PTR(ptr) & ~ PREV_FREE) < MIN_BLOCK) { - malloc_printf("ptr=%p this=%d msize=%d\n", ptr, MSIZE_FLAGS_FOR_PTR(ptr), (int)msize); - szone_error(szone, "Pointer allocated has improper size (2)", ptr); - return NULL; - } + if (LOG(szone, ptr)) malloc_printf("In szone_free with %p\n", ptr); #endif + if (!ptr) return; + if ((vm_address_t)ptr & (TINY_QUANTUM - 1)) { + szone_error(szone, "Non-aligned pointer being freed", ptr); + return; + } + // try a tiny pointer + tiny_region_t *tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); + if (tiny_region) { + free_tiny(szone, ptr, tiny_region); + return; + } + if ((vm_address_t)ptr & (SMALL_QUANTUM - 1)) { + szone_error(szone, "Non-aligned pointer being freed (2)", ptr); + return; + } + // try a small pointer + small_region_t *small_region = small_region_for_ptr_no_lock(szone, ptr); + if (small_region) { + free_small(szone, ptr, small_region); + return; + } + if (((unsigned)ptr) & ((1 << vm_page_shift) - 1)) { + szone_error(szone, "Non-page-aligned, non-allocated pointer being freed", ptr); + return; + } + free_large_or_huge(szone, ptr); +} + +static INLINE void * +szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) { + void *ptr; + if (size <= 31*TINY_QUANTUM) { + // think tiny + msize_t msize = (size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM; + if (! msize) msize = 1; + ptr = tiny_malloc_should_clear(szone, msize, cleared_requested); + } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) { + // think small + msize_t msize = (size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM; + if (! msize) msize = 1; + ptr = small_malloc_should_clear(szone, msize, cleared_requested); } else { - unsigned num_pages; - num_pages = round_page(size) >> vm_page_shift; - ptr = large_and_huge_malloc(szone, num_pages); + unsigned num_pages; + num_pages = round_page(size) >> vm_page_shift; + ptr = large_and_huge_malloc(szone, num_pages); } +#if DEBUG_MALLOC if (LOG(szone, ptr)) malloc_printf("szone_malloc returned %p\n", ptr); +#endif return ptr; } -static void *szone_malloc(szone_t *szone, size_t size) { - return szone_malloc_should_clear(szone, size, 0); +static void * +szone_malloc(szone_t *szone, size_t size) { + // malloc_printf("szone_malloc(%d)\n", size); + void *ptr = szone_malloc_should_clear(szone, size, 0); + // malloc_printf("szone_malloc(%d) -> %p %d\n", size, ptr, malloc_size(ptr)); + return ptr; } -static void *szone_calloc(szone_t *szone, size_t num_items, size_t size) { - return szone_malloc_should_clear(szone, num_items * size, 1); +static void * +szone_calloc(szone_t *szone, size_t num_items, size_t size) { + // malloc_printf("szone_calloc(%d,%d)\n", num_items, size); + void *ptr = szone_malloc_should_clear(szone, num_items * size, 1); + // malloc_printf("szone_calloc(%d,%d) -> %p\n", num_items, size, ptr); + return ptr; } -static void *szone_valloc(szone_t *szone, size_t size) { +static void * +szone_valloc(szone_t *szone, size_t size) { void *ptr; unsigned num_pages; num_pages = round_page(size) >> vm_page_shift; ptr = large_and_huge_malloc(szone, num_pages); +#if DEBUG_MALLOC if (LOG(szone, ptr)) malloc_printf("szone_valloc returned %p\n", ptr); +#endif return ptr; } -static size_t szone_size(szone_t *szone, const void *ptr) { +static size_t +szone_size(szone_t *szone, const void *ptr) { size_t size = 0; - region_t *region; large_entry_t *entry; huge_entry_t *huge; + // malloc_printf("szone_size(%p)\n", ptr); if (!ptr) return 0; - if (LOG(szone, ptr)) malloc_printf("In szone_size for %p (szone=%p)\n", ptr, szone); - if ((vm_address_t)ptr & (QUANTUM - 1)) return 0; - if ((((unsigned)ptr) & (vm_page_size - 1)) && (MSIZE_FLAGS_FOR_PTR(ptr) & THIS_FREE)) { - // not page aligned, but definitely not in use - return 0; - } - // Try a small pointer - region = region_for_ptr_no_lock(szone, ptr); - // malloc_printf("FOUND REGION %p\n", region); - if (region) { - // this is indeed a valid pointer - msize_t msize_and_free = MSIZE_FLAGS_FOR_PTR(ptr); - return (msize_and_free & THIS_FREE) ? 0 : ((msize_and_free & ~PREV_FREE) << SHIFT_QUANTUM) - PTR_HEADER_SIZE; - } - if (((unsigned)ptr) & (vm_page_size - 1)) { - return 0; +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("In szone_size for %p (szone=%p)\n", ptr, szone); + } +#endif + if ((vm_address_t)ptr & (TINY_QUANTUM - 1)) return 0; + // Try tiny + tiny_region_t *tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); + if (tiny_region) { + // this is indeed a valid pointer + boolean_t is_free; + msize_t msize = get_tiny_meta_header(ptr, &is_free); + return (is_free) ? 0 : msize << SHIFT_TINY_QUANTUM; + } + if ((vm_address_t)ptr & (SMALL_QUANTUM - 1)) return 0; + // Try a small + small_region_t *small_region = small_region_for_ptr_no_lock(szone, ptr); + if (small_region) { + // this is indeed a valid pointer + msize_t msize_and_free = small_meta_header(ptr)[0]; + return (msize_and_free & SMALL_IS_FREE) ? 0 : msize_and_free << SHIFT_SMALL_QUANTUM; + } + if (((unsigned)ptr) & ((1 << vm_page_shift) - 1)) { + // malloc_printf("Object %p not found in szone_size\n", ptr); + return 0; } SZONE_LOCK(szone); entry = large_entry_for_pointer_no_lock(szone, ptr); if (entry) { - size = LARGE_ENTRY_SIZE(*entry); + size = LARGE_ENTRY_SIZE(*entry); } else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) { - size = huge->size; + size = huge->size; } SZONE_UNLOCK(szone); // malloc_printf("szone_size for large/huge %p returned %d\n", ptr, (unsigned)size); - if (LOG(szone, ptr)) malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size); + } +#endif return size; } -static INLINE int try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { - // returns 1 on success - void *next_block = (char *)ptr + old_size + PTR_HEADER_SIZE; - msize_t next_msize_and_free; - msize_t next_msize; - region_t region; - msize_t coalesced_msize; - msize_t leftover_msize; - msize_t new_msize_and_free; - void *following_ptr; - SZONE_LOCK(szone); - region = szone->regions[szone->num_regions - 1]; - if (((vm_address_t)ptr >= region) && ((vm_address_t)ptr < region + REGION_SIZE) && ((vm_address_t)next_block == REGION_END(region) - szone->num_bytes_free_in_last_region + PTR_HEADER_SIZE)) { - // This could be optimized but it is so rare it's not worth it - SZONE_UNLOCK(szone); - return 0; - } - // If the next block is free, we coalesce - next_msize_and_free = MSIZE_FLAGS_FOR_PTR(next_block); +static void * +szone_realloc(szone_t *szone, void *ptr, size_t new_size) { + size_t old_size = 0; + void *new_ptr; + // malloc_printf("szone_realloc(%p,%d)\n", ptr, new_size); #if DEBUG_MALLOC - if ((vm_address_t)next_block & (QUANTUM - 1)) { - szone_error(szone, "Internal invariant broken in realloc(next_block)", next_block); - } - if (next_msize_and_free & PREV_FREE) { - malloc_printf("try_realloc_small_in_place: 0x%x=PREV_FREE|%d\n", next_msize_and_free, next_msize_and_free & ~PREV_FREE); - SZONE_UNLOCK(szone); - return 0; + if (LOG(szone, ptr)) { + malloc_printf("In szone_realloc for %p, %d\n", ptr, (unsigned)new_size); } #endif - next_msize = next_msize_and_free & ~THIS_FREE; - if (!(next_msize_and_free & THIS_FREE) || !next_msize || (old_size + (next_msize << SHIFT_QUANTUM) < new_size)) { - SZONE_UNLOCK(szone); - return 0; + if (!ptr) { + ptr = szone_malloc(szone, new_size); + // malloc_printf("szone_realloc(%p,%d) -> %p\n", ptr, new_size, ptr); + return ptr; + } + old_size = szone_size(szone, ptr); + if (!old_size) { + szone_error(szone, "Pointer being reallocated was not allocated", ptr); + return NULL; } - coalesced_msize = (new_size - old_size + QUANTUM - 1) >> SHIFT_QUANTUM; - leftover_msize = next_msize - coalesced_msize; - new_msize_and_free = MSIZE_FLAGS_FOR_PTR(ptr); - // malloc_printf("Realloc in place for %p; current msize=%d next_msize=%d wanted=%d\n", ptr, MSIZE_FLAGS_FOR_PTR(ptr), next_msize, new_size); - free_list_remove_ptr(szone, next_block, next_msize); - if ((leftover_msize < MIN_BLOCK) || (leftover_msize < coalesced_msize / 4)) { - // don't bother splitting it off - // malloc_printf("No leftover "); - coalesced_msize = next_msize; - leftover_msize = 0; + /* we never shrink an allocation */ + if (old_size >= new_size) return ptr; + if ((new_size + TINY_QUANTUM - 1) <= 31 * TINY_QUANTUM) { + // We now try to realloc in place + if (try_realloc_tiny_in_place(szone, ptr, old_size, new_size)) { + // malloc_printf("szone_realloc(%p,%d) -> %p\n", ptr, new_size, ptr); + return ptr; + } + } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && ((new_size + SMALL_QUANTUM - 1) < LARGE_THRESHOLD) && (old_size > 31 * TINY_QUANTUM)) { + // We now try to realloc in place + if (try_realloc_small_in_place(szone, ptr, old_size, new_size)) { + // malloc_printf("szone_realloc(%p,%d) small in place -> %p\n", ptr, new_size, ptr); + return ptr; + } + } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (old_size > LARGE_THRESHOLD)) { + if (try_realloc_large_or_huge_in_place(szone, ptr, old_size, new_size)) { + return ptr; + } + } + new_ptr = szone_malloc(szone, new_size); + if (new_ptr == NULL) return NULL; + if ((old_size > VM_COPY_THRESHOLD) && (new_size > VM_COPY_THRESHOLD)) { + // we know everything is page-aligned try vm_copy + kern_return_t err = 0; + err = vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr); + if (err) { + szone_error(szone, "Can't vm_copy region", ptr); + } } else { - void *leftover = next_block + (coalesced_msize << SHIFT_QUANTUM); - // malloc_printf("Leftover "); - free_list_add_ptr(szone, leftover, leftover_msize); - } - new_msize_and_free += coalesced_msize; - MSIZE_FLAGS_FOR_PTR(ptr) = new_msize_and_free; - following_ptr = FOLLOWING_PTR(ptr, new_msize_and_free & ~PREV_FREE); - MSIZE_FLAGS_FOR_PTR(following_ptr) &= ~ PREV_FREE; + memcpy(new_ptr, ptr, old_size); + } + szone_free(szone, ptr); #if DEBUG_MALLOC - { - msize_t ms = MSIZE_FLAGS_FOR_PTR(following_ptr); - msize_t pms = PREVIOUS_MSIZE(FOLLOWING_PTR(following_ptr, ms & ~THIS_FREE)); - malloc_printf("Following ptr of coalesced (%p) has msize_and_free=0x%x=%s%d end_of_block_marker=%d\n", following_ptr, ms, (ms & THIS_FREE) ? "THIS_FREE|" : "", ms & ~THIS_FREE, pms); + if (LOG(szone, ptr)) { + malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); } - if (LOG(szone,ptr)) malloc_printf("In szone_realloc(), ptr=%p, msize=%d\n", ptr, MSIZE_FLAGS_FOR_PTR(ptr)); #endif - CHECK(szone, __PRETTY_FUNCTION__); - szone->num_bytes_in_small_objects += coalesced_msize << SHIFT_QUANTUM; - SZONE_UNLOCK(szone); - // malloc_printf("Extended ptr %p for realloc old=%d desired=%d new=%d leftover=%d\n", ptr, (unsigned)old_size, (unsigned)new_size, (unsigned)szone_size(szone, ptr), leftover_msize << SHIFT_QUANTUM); - return 1; + // malloc_printf("szone_realloc(%p,%d) -> %p\n", ptr, new_size, new_ptr); + return new_ptr; } -static INLINE int try_realloc_large_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) { - vm_address_t addr = (vm_address_t)ptr + old_size; - large_entry_t *entry; - kern_return_t err; - if (((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL)) return 0; // don't want to bother with the protected case -#if DEBUG_MALLOC - if (old_size != ((old_size >> vm_page_shift) << vm_page_shift)) malloc_printf("*** old_size is %d\n", old_size); -#endif - // malloc_printf("=== Trying (1) to extend %p from %d to %d\n", ptr, old_size, new_size); - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, (void *)addr); +unsigned +szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) { + // 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 + // malloc_printf("In szone_batch_malloc(%d, %d)\n", size, count); + if (size > 31*TINY_QUANTUM) return 0; // only bother implementing this for tiny + msize_t msize = (size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM; + if (! msize) msize = 1; + size_t chunk_size = msize << SHIFT_TINY_QUANTUM; + unsigned found = 0; + CHECK(szone, __PRETTY_FUNCTION__); + SZONE_LOCK(szone); // might as well lock right here to avoid concurrency issues + free_list_t **free_list = szone->tiny_free_list + msize - 1; + free_list_t *ptr = *free_list; + while (found < count) { + if (!ptr) break; + *results++ = ptr; found++; + set_tiny_meta_header_in_use(ptr, msize); + ptr = ((free_list_t *)ptr)->next; + } + if (ptr) { + ((free_list_t *)ptr)->previous = NULL; + free_list_set_checksum(szone, (free_list_t *)ptr); + } + *free_list = (void *)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); - if (entry) return 0; // large pointer already exist in table - extension is not going to work - new_size = round_page(new_size); - // malloc_printf("=== Trying (2) to extend %p from %d to %d\n", ptr, old_size, new_size); - err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE)); // we ask for allocation specifically at addr - if (err) return 0; - // we can just extend the block - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!entry) szone_error(szone, "large entry reallocated is not properly in table", ptr); - // malloc_printf("=== Successfully reallocated at end of %p from %d to %d\n", ptr, old_size, new_size); - entry->address_and_num_pages = (vm_address_t)ptr | (new_size >> vm_page_shift); - szone->num_bytes_in_large_objects += new_size - old_size; - SZONE_UNLOCK(szone); // we release the lock asap - return 1; + // malloc_printf("In szone_batch_malloc(%d, %d) -> %d\n", size, count, found); + return found; } -static void *szone_realloc(szone_t *szone, void *ptr, size_t new_size) { - size_t old_size = 0; - void *new_ptr; - if (LOG(szone, ptr)) malloc_printf("In szone_realloc for %p, %d\n", ptr, (unsigned)new_size); - if (!ptr) return szone_malloc(szone, new_size); - old_size = szone_size(szone, ptr); - if (!old_size) { - szone_error(szone, "Pointer being reallocated was not allocated", ptr); - return NULL; +void +szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) { + // frees all the pointers in to_be_freed + // note that to_be_freed may be overwritten during the process + if (!count) return; + // malloc_printf("Freeing %d items\n", count); + unsigned cc = 0; + CHECK(szone, __PRETTY_FUNCTION__); + SZONE_LOCK(szone); + while (cc < count) { + void *ptr = to_be_freed[cc]; + tiny_region_t *tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); + if (tiny_region) { + // this is a tiny pointer + boolean_t is_free; + msize_t 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++; } - if (old_size >= new_size) return ptr; - if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && ((new_size + PTR_HEADER_SIZE + QUANTUM - 1) < LARGE_THRESHOLD)) { - // We now try to realloc in place - if (try_realloc_small_in_place(szone, ptr, old_size, new_size)) return ptr; - } - if ((old_size > VM_COPY_THRESHOLD) && ((new_size + vm_page_size - 1) < (1 << (vm_page_shift + vm_page_shift)))) { - // we know it's a large block, and not a huge block (both for old and new) - kern_return_t err = 0; - unsigned num_pages; - large_entry_t *entry; - vm_range_t range; - num_pages = round_page(new_size) >> vm_page_shift; - if (try_realloc_large_in_place(szone, ptr, old_size, new_size)) return ptr; - new_ptr = large_and_huge_malloc(szone, num_pages); - err = vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr); - if (err) { - szone_error(szone, "Can't vm_copy region", ptr); - } - // We do not want the kernel to alias the old and the new, so we deallocate the old pointer right away and tear down the ptr-to-size data structure - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!entry) { - szone_error(szone, "Can't find entry for large copied block", ptr); - } - range = large_free_no_lock(szone, entry); - SZONE_UNLOCK(szone); // we release the lock asap - // we truly deallocate_pages, including guard pages - deallocate_pages(szone, range.address, range.size, 0); - if (LOG(szone, ptr)) malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); - return new_ptr; - } else { - new_ptr = szone_malloc(szone, new_size); - if (new_ptr == NULL) - return NULL; - memcpy(new_ptr, ptr, old_size); + SZONE_UNLOCK(szone); + CHECK(szone, __PRETTY_FUNCTION__); + while (count--) { + void *ptr = to_be_freed[count]; + // malloc_printf("Freeing item at %d: %p\n", count, ptr); + if (ptr) szone_free(szone, ptr); } - szone_free(szone, ptr); - if (LOG(szone, ptr)) malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); - return new_ptr; } -static void szone_destroy(szone_t *szone) { +static void +szone_destroy(szone_t *szone) { unsigned index; + small_region_t pended_region = 0; index = szone->num_large_entries; while (index--) { - large_entry_t *entry = szone->large_entries + index; - if (!LARGE_ENTRY_IS_EMPTY(*entry)) { - large_entry_t range; - range = *entry; - // we deallocate_pages, including guard pages - deallocate_pages(szone, LARGE_ENTRY_ADDRESS(range), LARGE_ENTRY_SIZE(range), szone->debug_flags); - } - } - if (szone->num_large_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD) large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries); // we do not free in the small chunk case + large_entry_t *entry = szone->large_entries + index; + if (!LARGE_ENTRY_IS_EMPTY(*entry)) { + large_entry_t range; + range = *entry; + // we deallocate_pages, including guard pages + deallocate_pages(szone, LARGE_ENTRY_ADDRESS(range), LARGE_ENTRY_SIZE(range), szone->debug_flags); + } + } + if (szone->num_large_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD) { + vm_range_t range_to_deallocate; + large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); // we do not free in the small chunk case + if (range_to_deallocate.size) deallocate_pages(szone, range_to_deallocate.address, range_to_deallocate.size, 0); + + } index = szone->num_huge_entries; while (index--) { - huge_entry_t *huge = szone->huge_entries + index; - deallocate_pages(szone, huge->address, huge->size, szone->debug_flags); + huge_entry_t *huge = szone->huge_entries + index; + deallocate_pages(szone, huge->address, huge->size, szone->debug_flags); + } + // the tiny regions + index = szone->num_tiny_regions; + while (index--) { + tiny_region_t tiny_region = szone->tiny_regions[index]; + vm_size_t size_allocated = ((TINY_REGION_SIZE + (1 << vm_page_shift) - 1) >> vm_page_shift) << vm_page_shift; + deallocate_pages(szone, TINY_REGION_ADDRESS(tiny_region), size_allocated, 0); } // and now we free regions, with regions[0] as the last one (the final harakiri) - index = szone->num_regions; - while (index--) { // we skip the first region, that is the zone itself - region_t region = szone->regions[index]; - deallocate_pages(szone, REGION_ADDRESS(region), REGION_SIZE, 0); + index = szone->num_small_regions; + while (index--) { + small_region_t region = szone->small_regions[index]; + if (index > 0 + && (void *)szone->small_regions >= (void *)(SMALL_REGION_ADDRESS(region)) + && (void *)szone->small_regions < (void *)(SMALL_REGION_END(region))) { + // Pend deallocation of this region, since the region + // bookkeeping array is in it. + pended_region = region; + } else { + deallocate_pages(szone, SMALL_REGION_ADDRESS(region), SMALL_REGION_SIZE, 0); + } + } + if (pended_region) { + deallocate_pages(szone, SMALL_REGION_ADDRESS(pended_region), SMALL_REGION_SIZE, 0); } } -static size_t szone_good_size(szone_t *szone, size_t size) { +static size_t +szone_good_size(szone_t *szone, size_t size) { + if (size <= 31 * TINY_QUANTUM) { + // think tiny + msize_t msize = (size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM; + if (! msize) msize = 1; + return msize << SHIFT_TINY_QUANTUM; + } if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) { - // think small - msize_t msize = (size + PTR_HEADER_SIZE + QUANTUM - 1) >> SHIFT_QUANTUM; - if (msize < MIN_BLOCK) msize = MIN_BLOCK; - return (msize << SHIFT_QUANTUM) - PTR_HEADER_SIZE; + // think small + msize_t msize = (size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM; + if (! msize) msize = 1; + return msize << SHIFT_SMALL_QUANTUM; } else { - unsigned num_pages; - num_pages = round_page(size) >> vm_page_shift; - if (!num_pages) num_pages = 1; // minimal allocation size for this - return num_pages << vm_page_shift; + unsigned num_pages; + num_pages = round_page(size) >> vm_page_shift; + if (!num_pages) num_pages = 1; // minimal allocation size for this + return num_pages << vm_page_shift; } } @@ -1377,160 +2817,252 @@ unsigned szone_check_counter = 0; unsigned szone_check_start = 0; unsigned szone_check_modulo = 1; -static boolean_t szone_check_all(szone_t *szone, const char *function) { +static boolean_t +szone_check_all(szone_t *szone, const char *function) { unsigned index = 0; SZONE_LOCK(szone); - while (index < szone->num_regions) { - region_t *region = szone->regions + index++; - if (!szone_check_region(szone, region)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - malloc_printf("*** malloc[%d]: Region %d incorrect szone_check_all(%s) counter=%d\n", getpid(), index-1, function, szone_check_counter); - szone_error(szone, "Check: region incorrect", NULL); - return 0; - } + CHECK_LOCKED(szone, __PRETTY_FUNCTION__); + while (index < szone->num_tiny_regions) { + tiny_region_t *region = szone->tiny_regions + index++; + if (! szone_check_tiny_region(szone, region)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + malloc_printf("*** malloc[%d]: Tiny region %d incorrect szone_check_all(%s) counter=%d\n", getpid(), index-1, function, szone_check_counter); + szone_error(szone, "Check: tiny region incorrect", NULL); + return 0; + } + } + + index = 0; + while (index < NUM_TINY_SLOTS) { + if (! tiny_free_list_check(szone, index)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + malloc_printf("*** malloc[%d]: Tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n", getpid(), index, function, szone_check_counter); + szone_error(szone, "Check: tiny free list incorrect", NULL); + return 0; + } + index++; + } + + index = 0; while (index < szone->num_small_regions) { + small_region_t *region = szone->small_regions + index++; + if (! szone_check_small_region(szone, region)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + malloc_printf("*** malloc[%d]: Small region %d incorrect szone_check_all(%s) counter=%d\n", getpid(), index-1, function, szone_check_counter); + szone_error(szone, "Check: small region incorrect", NULL); + return 0; + } } index = 0; - while (index < MAX_GRAIN) { - if (! free_list_check(szone, index)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - malloc_printf("*** malloc[%d]: Free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", getpid(), index, function, szone_check_counter); - szone_error(szone, "Check: free list incorrect", NULL); - return 0; - } - index++; + while (index < NUM_SMALL_SLOTS) { + if (! small_free_list_check(szone, index)) { + SZONE_UNLOCK(szone); + szone->debug_flags &= ~ CHECK_REGIONS; + malloc_printf("*** malloc[%d]: Small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", getpid(), index, function, szone_check_counter); + szone_error(szone, "Check: small free list incorrect", NULL); + return 0; + } + index++; } SZONE_UNLOCK(szone); + // szone_print(szone, 1); return 1; } -static boolean_t szone_check(szone_t *szone) { +static boolean_t +szone_check(szone_t *szone) { if (! (++szone_check_counter % 10000)) { - malloc_printf("At szone_check counter=%d\n", szone_check_counter); + malloc_printf("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) return 1; return szone_check_all(szone, ""); } -static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder) { +static kern_return_t +szone_ptr_in_use_enumerator(task_t task, void *context, + unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, + vm_range_recorder_t recorder) { szone_t *szone; kern_return_t err; if (!reader) reader = _szone_default_reader; - // malloc_printf("Enumerator for zone 0x%x\n", zone_address); +// malloc_printf("Enumerator for zone %p\n", zone_address); err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); if (err) return err; - // malloc_printf("Small ptrs enumeration for zone 0x%x\n", zone_address); - err = small_in_use_enumerator(task, context, type_mask, (vm_address_t)szone->regions, szone->num_regions, reader, recorder); +// malloc_printf("Tiny ptrs enumeration for zone %p\n", zone_address); + 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); if (err) return err; - // malloc_printf("Large ptrs enumeration for zone 0x%x\n", zone_address); - err = large_in_use_enumerator(task, context, type_mask, (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); +// malloc_printf("Small ptrs enumeration for zone %p\n", zone_address); + 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); if (err) return err; - // malloc_printf("Huge ptrs enumeration for zone 0x%x\n", zone_address); - err = huge_in_use_enumerator(task, context, type_mask, (vm_address_t)szone->huge_entries, szone->num_huge_entries, reader, recorder); +// malloc_printf("Large ptrs enumeration for zone %p\n", zone_address); + err = large_in_use_enumerator(task, context, type_mask, + (vm_address_t)szone->large_entries, szone->num_large_entries, reader, + recorder); + if (err) return err; +// malloc_printf("Huge ptrs enumeration for zone %p\n", zone_address); + err = huge_in_use_enumerator(task, context, type_mask, + (vm_address_t)szone->huge_entries, szone->num_huge_entries, reader, + recorder); return err; } -static void szone_print_free_list(szone_t *szone) { - grain_t grain = MAX_GRAIN; - malloc_printf("Free Sizes: "); - while (grain--) { - free_list_t *ptr = szone->free_list[grain]; - if (ptr) { - unsigned count = 0; - while (ptr) { - count++; - // malloc_printf("%p ", ptr); - ptr = ptr->next; - } - malloc_printf("%s%d[%d] ", (grain == MAX_GRAIN-1) ? ">=" : "", (grain+1)*QUANTUM, count); - } - } - malloc_printf("\n"); +// Following method is deprecated: use scalable_zone_statistics instead +void +scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) { + szone_t *szone = (void *)zone; + unsigned info[13]; + // We do not lock to facilitate debug + info[4] = szone->num_tiny_objects; + info[5] = szone->num_bytes_in_tiny_objects; + info[6] = szone->num_small_objects; + info[7] = szone->num_bytes_in_small_objects; + info[8] = szone->num_large_objects_in_use; + info[9] = szone->num_bytes_in_large_objects; + info[10] = szone->num_huge_entries; + info[11] = szone->num_bytes_in_huge_objects; + info[12] = szone->debug_flags; + info[0] = info[4] + info[6] + info[8] + info[10]; + info[1] = info[5] + info[7] + info[9] + info[11]; + info[3] = szone->num_tiny_regions * TINY_REGION_SIZE + szone->num_small_regions * SMALL_REGION_SIZE + info[9] + info[11]; + info[2] = info[3] - szone->tiny_bytes_free_at_end - szone->small_bytes_free_at_end; + memcpy(info_to_fill, info, sizeof(unsigned)*count); } -static void szone_print(szone_t *szone, boolean_t verbose) { - unsigned info[scalable_zone_info_count]; +static void +szone_print(szone_t *szone, boolean_t verbose) { + unsigned info[13]; unsigned index = 0; - scalable_zone_info((void *)szone, info, scalable_zone_info_count); - malloc_printf("Scalable zone %p: inUse=%d(%dKB) small=%d(%dKB) large=%d(%dKB) huge=%d(%dKB) guard_page=%d\n", szone, info[0], info[1] / 1024, info[2], info[3] / 1024, info[4], info[5] / 1024, info[6], info[7] / 1024, info[8]); - malloc_printf("%d regions: \n", szone->num_regions); - while (index < szone->num_regions) { - region_t *region = szone->regions + index; - unsigned counts[512]; - unsigned ci = 0; - unsigned in_use = 0; - vm_address_t start = REGION_ADDRESS(*region) + QUANTUM; - memset(counts, 0, 512 * sizeof(unsigned)); - while (start < REGION_END(*region)) { - msize_t msize_and_free = MSIZE_FLAGS_FOR_PTR(start); - if (!(msize_and_free & THIS_FREE)) { - msize_t msize = msize_and_free & ~PREV_FREE; - if (!msize) break; // last encountered - // block in use - if (msize < 512) counts[msize]++; - start += msize << SHIFT_QUANTUM; - in_use++; - } else { - msize_t msize = msize_and_free & ~THIS_FREE; - // free block - start += msize << SHIFT_QUANTUM; - } - } - malloc_printf("Region [0x%x-0x%x, %dKB] \tIn_use=%d ", REGION_ADDRESS(*region), REGION_END(*region), (int)REGION_SIZE / 1024, in_use); - if (verbose) { - malloc_printf("\n\tSizes in use: "); - while (ci < 512) { - if (counts[ci]) malloc_printf("%d[%d] ", ci << SHIFT_QUANTUM, counts[ci]); - ci++; - } - } - malloc_printf("\n"); - index++; - } - if (verbose) szone_print_free_list(szone); - malloc_printf("Free in last zone %d\n", szone->num_bytes_free_in_last_region); -} - -static void szone_log(malloc_zone_t *zone, void *log_address) { + 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) { + tiny_region_t *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) { + small_region_t *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); +} + +static void +szone_log(malloc_zone_t *zone, void *log_address) { szone_t *szone = (void *)zone; szone->log_address = log_address; } -static void szone_force_lock(szone_t *szone) { - // malloc_printf("szone_force_lock\n"); +static void +szone_force_lock(szone_t *szone) { +// malloc_printf("szone_force_lock\n"); SZONE_LOCK(szone); } -static void szone_force_unlock(szone_t *szone) { - // malloc_printf("szone_force_unlock\n"); +static void +szone_force_unlock(szone_t *szone) { +// malloc_printf("szone_force_unlock\n"); SZONE_UNLOCK(szone); } -static struct malloc_introspection_t szone_introspect = {(void *)szone_ptr_in_use_enumerator, (void *)szone_good_size, (void *)szone_check, (void *)szone_print, szone_log, (void *)szone_force_lock, (void *)szone_force_unlock}; +boolean_t +scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) { + szone_t *szone = (void *)zone; + switch (subzone) { + case 0: + stats->blocks_in_use = szone->num_tiny_objects; + stats->size_in_use = szone->num_bytes_in_tiny_objects; + stats->size_allocated = szone->num_tiny_regions * TINY_REGION_SIZE; + stats->max_size_in_use = stats->size_allocated - szone->tiny_bytes_free_at_end; + return 1; + case 1: + stats->blocks_in_use = szone->num_small_objects; + stats->size_in_use = szone->num_bytes_in_small_objects; + stats->size_allocated = szone->num_small_regions * SMALL_REGION_SIZE; + stats->max_size_in_use = stats->size_allocated - szone->small_bytes_free_at_end; + return 1; + case 2: + stats->blocks_in_use = szone->num_large_objects_in_use; + stats->size_in_use = szone->num_bytes_in_large_objects; + stats->max_size_in_use = stats->size_allocated = stats->size_in_use; + return 1; + case 3: + stats->blocks_in_use = szone->num_huge_entries; + stats->size_in_use = szone->num_bytes_in_huge_objects; + stats->max_size_in_use = stats->size_allocated = stats->size_in_use; + return 1; + } + return 0; +} + +static void +szone_statistics(szone_t *szone, malloc_statistics_t *stats) { + stats->blocks_in_use = szone->num_tiny_objects + szone->num_small_objects + szone->num_large_objects_in_use + szone->num_huge_entries; + size_t big_and_huge = szone->num_bytes_in_large_objects + szone->num_bytes_in_huge_objects; + stats->size_in_use = szone->num_bytes_in_tiny_objects + szone->num_bytes_in_small_objects + big_and_huge; + stats->max_size_in_use = stats->size_allocated = szone->num_tiny_regions * TINY_REGION_SIZE + szone->num_small_regions * SMALL_REGION_SIZE + big_and_huge ; + // Now we account for the untouched areas + stats->max_size_in_use -= szone->tiny_bytes_free_at_end; + stats->max_size_in_use -= szone->small_bytes_free_at_end; +} -malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_flags) { +static const struct malloc_introspection_t szone_introspect = { + (void *)szone_ptr_in_use_enumerator, + (void *)szone_good_size, + (void *)szone_check, + (void *)szone_print, + szone_log, + (void *)szone_force_lock, + (void *)szone_force_unlock, + (void *)szone_statistics +}; // marked as const to spare the DATA section + +malloc_zone_t * +create_scalable_zone(size_t initial_size, unsigned debug_flags) { szone_t *szone; vm_address_t addr; size_t msize; size_t msize_used = 0; - // malloc_printf("=== create_scalable_zone(%d,%d);\n", initial_size, debug_flags); + // malloc_printf("=== create_scalable_zone(%d,%d) - %s\n", initial_size, debug_flags, (DEBUG_MALLOC) ? "**** DEBUG" : ""); +#if PAGE_SIZE_FIXED + if ((1 << vm_page_shift) == vm_page_size) { + // malloc_printf("vm_page_shift validated to be %d\n", vm_page_shift); + } else { + malloc_printf("*** vm_page_shift incorrectly set to %d\n", vm_page_shift); + exit(-1); + } +#else if (!vm_page_shift) { - unsigned page; - vm_page_shift = 12; // the minimal for page sizes - page = 1 << vm_page_shift; - while (page != vm_page_size) { page += page; vm_page_shift++;}; - if (MIN_BLOCK * QUANTUM < sizeof(free_list_t) + PTR_HEADER_SIZE) { - malloc_printf("*** malloc[%d]: inconsistant parameters\n", getpid()); - } - } - addr = allocate_pages(NULL, REGION_SIZE, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC)); + unsigned page; + vm_page_shift = 12; // the minimal for page sizes + page = 1 << vm_page_shift; + while (page != vm_page_size) { page += page; vm_page_shift++;}; + } +#endif + addr = allocate_pages(NULL, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC)); if (!addr) return NULL; - szone = (void *)(addr + QUANTUM); - msize = (sizeof(szone_t) + PTR_HEADER_SIZE + QUANTUM-1) >> SHIFT_QUANTUM; - MSIZE_FLAGS_FOR_PTR(szone) = msize; + szone = (void *)addr; + msize = (sizeof(szone_t) + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM; + // malloc_printf("sizeof(szone_t)=%d msize for 1st block=%d; wasted %d bytes\n", sizeof(szone_t), msize, (msize << SHIFT_SMALL_QUANTUM) - sizeof(szone_t)); + small_meta_header(szone)[0] = msize; + szone->tiny_regions = szone->initial_tiny_regions; + szone->small_regions = szone->initial_small_regions; msize_used += msize; szone->num_small_objects++; + szone->basic_zone.version = 3; szone->basic_zone.size = (void *)szone_size; szone->basic_zone.malloc = (void *)szone_malloc; szone->basic_zone.calloc = (void *)szone_calloc; @@ -1538,40 +3070,31 @@ malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_flags) { szone->basic_zone.free = (void *)szone_free; szone->basic_zone.realloc = (void *)szone_realloc; szone->basic_zone.destroy = (void *)szone_destroy; - szone->basic_zone.introspect = &szone_introspect; + szone->basic_zone.batch_malloc = (void *)szone_batch_malloc; + szone->basic_zone.batch_free = (void *)szone_batch_free; + szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; LOCK_INIT(szone->lock); +#if 0 +#warning CHECK_REGIONS enabled + debug_flags |= CHECK_REGIONS; +#endif +#if 0 +#warning LOG enabled + szone->log_address = ~0; +#endif szone->debug_flags = debug_flags; - szone->regions = (void *)((char *)szone + (msize << SHIFT_QUANTUM)); - // we always reserve room for a few regions - msize = (sizeof(region_t) * INITIAL_NUM_REGIONS + PTR_HEADER_SIZE + QUANTUM-1) >> SHIFT_QUANTUM; - if (msize < MIN_BLOCK) msize = MIN_BLOCK; - MSIZE_FLAGS_FOR_PTR(szone->regions) = msize; - msize_used += msize; szone->num_small_objects++; - szone->regions[0] = addr; - szone->num_regions = 1; - szone->num_bytes_free_in_last_region = REGION_SIZE - ((msize_used+1) << SHIFT_QUANTUM) + PTR_HEADER_SIZE; + szone->small_regions[0] = addr >> SMALL_BLOCKS_ALIGN; + szone->num_small_regions = 1; + msize_t free_msize = NUM_SMALL_BLOCKS - msize; + small_meta_header(szone)[msize] = free_msize; + szone->small_bytes_free_at_end = free_msize << SHIFT_SMALL_QUANTUM; CHECK(szone, __PRETTY_FUNCTION__); +#if 0 + write(1, "Malloc szone created\n", 23); +#endif return (malloc_zone_t *)szone; } -/********* The following is private API for debug and perf tools ************/ - -void scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) { - szone_t *szone = (void *)zone; - unsigned info[scalable_zone_info_count]; - // We do not lock to facilitate debug - info[2] = szone->num_small_objects; - info[3] = szone->num_bytes_in_small_objects; - info[4] = szone->num_large_objects_in_use; - info[5] = szone->num_bytes_in_large_objects; - info[6] = szone->num_huge_entries; - info[7] = szone->num_bytes_in_huge_objects; - info[8] = szone->debug_flags; - info[0] = info[2] + info[4] + info[6]; - info[1] = info[3] + info[5] + info[7]; - memcpy(info_to_fill, info, sizeof(unsigned)*count); -} - /********* Support code for emacs unexec ************/ /* History of freezedry version numbers: @@ -1584,12 +3107,13 @@ void scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned co * operations on freezedried memory. This doesn't work, since scalable * malloc does not store flags in front of large page-aligned allocations. * 3) Original szone-based freezedrying code. + * 4) Fresher malloc with tiny zone * * 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 3 +#define MALLOC_FREEZEDRY_VERSION 4 typedef struct { unsigned version; @@ -1597,39 +3121,41 @@ typedef struct { szone_t *szones; } malloc_frozen; -static void *frozen_malloc(szone_t *zone, size_t new_size) { +static void * +frozen_malloc(szone_t *zone, size_t new_size) { return malloc(new_size); } -static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size) { +static void * +frozen_calloc(szone_t *zone, size_t num_items, size_t size) { return calloc(num_items, size); } -static void *frozen_valloc(szone_t *zone, size_t new_size) { +static void * +frozen_valloc(szone_t *zone, size_t new_size) { return valloc(new_size); } -static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size) { +static void * +frozen_realloc(szone_t *zone, void *ptr, size_t new_size) { size_t old_size = szone_size(zone, ptr); void *new_ptr; - if (new_size <= old_size) { return ptr; } - new_ptr = malloc(new_size); - if (old_size > 0) { memcpy(new_ptr, ptr, old_size); } - return new_ptr; } -static void frozen_free(szone_t *zone, void *ptr) { +static void +frozen_free(szone_t *zone, void *ptr) { } -static void frozen_destroy(szone_t *zone) { +static void +frozen_destroy(szone_t *zone) { } /********* Pseudo-private API for emacs unexec ************/ @@ -1647,7 +3173,8 @@ static void frozen_destroy(szone_t *zone) { * returns 0 (error) if any non-szone zones are encountered. */ -int malloc_freezedry(void) { +int +malloc_freezedry(void) { extern unsigned malloc_num_zones; extern malloc_zone_t **malloc_zones; malloc_frozen *data; @@ -1656,8 +3183,7 @@ int malloc_freezedry(void) { /* Allocate space in which to store the freezedry state. */ data = (malloc_frozen *) malloc(sizeof(malloc_frozen)); - /* Set freezedry version number so that malloc_jumpstart() can check for - * compatibility. */ + /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */ data->version = MALLOC_FREEZEDRY_VERSION; /* Allocate the array of szone pointers. */ @@ -1680,7 +3206,8 @@ int malloc_freezedry(void) { return (int) data; } -int malloc_jumpstart(int cookie) { +int +malloc_jumpstart(int cookie) { malloc_frozen *data = (malloc_frozen *) cookie; unsigned i; @@ -1700,7 +3227,7 @@ int malloc_jumpstart(int cookie) { data->szones[i].basic_zone.free = (void *) frozen_free; data->szones[i].basic_zone.realloc = (void *) frozen_realloc; data->szones[i].basic_zone.destroy = (void *) frozen_destroy; - data->szones[i].basic_zone.introspect = &szone_introspect; + data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; /* Register the freezedried zone. */ malloc_zone_register(&data->szones[i].basic_zone); diff --git a/gen/scalable_malloc.h b/gen/scalable_malloc.h index 5f3841f..3d1b737 100644 --- a/gen/scalable_malloc.h +++ b/gen/scalable_malloc.h @@ -23,7 +23,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import +#import #define SCALABLE_MALLOC_ADD_GUARD_PAGES (1 << 0) // add a guard page before and after each VM region to help debug @@ -39,12 +39,9 @@ extern malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_f /***** Private API for debug and performance tools ********/ -#define scalable_zone_info_count 9 // maximum number of numbers - -extern void scalable_zone_info(malloc_zone_t *zone, unsigned *info, unsigned count); - /* Fills info[] with some statistical information: - info[0]: number of objects in use - info[1]: number of bytes in use - ... +extern boolean_t scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone); + /* Fills stats with some statistics; + 1 is returned on success; else 0 is returned + Currently: subzone=0 => tiny; subzone=1 => small; subzone=2 => large; subzone=3 => huge; any other subzone => returns 0 */ diff --git a/gen/setlogin.c b/gen/setlogin.c index befac5e..71d56b7 100644 --- a/gen/setlogin.c +++ b/gen/setlogin.c @@ -58,6 +58,8 @@ #include +extern int _setlogin(const char* name); + extern int _logname_valid; /* shared with getlogin() */ int setlogin(const char* name) diff --git a/gen/signal.c b/gen/signal.c deleted file mode 100644 index 98ebf9c..0000000 --- a/gen/signal.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 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. - */ - - -/* - * Almost backwards compatible signal. - */ -#include - -sigset_t _sigintr = 0; /* shared with siginterrupt */ - -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 - if (sigaction(s, &sa, &osa) < 0) - return (SIG_ERR); -#if defined(__DYNAMIC__) - } else { - if (_sigaction_nobind(s, &sa, &osa) < 0) - return (SIG_ERR); - } -#endif - 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 diff --git a/gen/sigsetops.c b/gen/sigsetops.c index e9019dc..cdfb895 100644 --- a/gen/sigsetops.c +++ b/gen/sigsetops.c @@ -65,6 +65,7 @@ #undef sigdelset #undef sigismember +int sigemptyset(set) sigset_t *set; { @@ -72,6 +73,7 @@ sigemptyset(set) return (0); } +int sigfillset(set) sigset_t *set; { @@ -79,6 +81,7 @@ sigfillset(set) return (0); } +int sigaddset(set, signo) sigset_t *set; int signo; @@ -91,6 +94,7 @@ sigaddset(set, signo) return (0); } +int sigdelset(set, signo) sigset_t *set; int signo; @@ -103,6 +107,7 @@ sigdelset(set, signo) return (0); } +int sigismember(set, signo) const sigset_t *set; int signo; @@ -111,5 +116,5 @@ sigismember(set, signo) errno = EINVAL; return(-1); } - return ((*set & ~sigmask(signo)) != 0); + return ((*set & sigmask(signo)) != 0); } diff --git a/gen/stack_logging.c b/gen/stack_logging.c index 6b170ef..4a38217 100644 --- a/gen/stack_logging.c +++ b/gen/stack_logging.c @@ -31,6 +31,8 @@ #import #import #include +#import +#import extern void spin_lock(int *); @@ -38,7 +40,8 @@ static inline void *allocate_pages(unsigned bytes) { void *address; if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes, VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) { - address = 0; + malloc_printf("malloc[%d]: Out of memory while stack logging\n", getpid()); + abort(); } return (void *)address; } diff --git a/gen/strtofflags.c b/gen/strtofflags.c index ba27a29..fdf353a 100644 --- a/gen/strtofflags.c +++ b/gen/strtofflags.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. diff --git a/gen/sysconf.3 b/gen/sysconf.3 index e3a47f1..4cb8187 100644 --- a/gen/sysconf.3 +++ b/gen/sysconf.3 @@ -85,6 +85,9 @@ and The maximum number of supplemental groups. .It Li _SC_OPEN_MAX The maximum number of open files per user id. +.It Li _SC_PAGESIZE +The memory page size of the system expressed in bytes. +This is the fundamental unit of memory management of the operating system. .It Li _SC_STREAM_MAX The minimum maximum number of streams that a process may have open at any one time. diff --git a/gen/sysconf.c b/gen/sysconf.c index bbcc564..a54ead5 100644 --- a/gen/sysconf.c +++ b/gen/sysconf.c @@ -83,7 +83,6 @@ long sysconf(name) int name; { - struct clockinfo clk; struct rlimit rl; size_t len; int mib[2], value; @@ -156,6 +155,10 @@ sysconf(name) mib[0] = CTL_USER; mib[1] = USER_LINE_MAX; break; + case _SC_PAGESIZE: + mib[0] = CTL_HW; + mib[1] = HW_PAGESIZE; + break; case _SC_RE_DUP_MAX: mib[0] = CTL_USER; mib[1] = USER_RE_DUP_MAX; diff --git a/gen/syslog.3 b/gen/syslog.3 index 663c6d8..39ea2cc 100644 --- a/gen/syslog.3 +++ b/gen/syslog.3 @@ -293,4 +293,4 @@ for later interpolation by .Pp Always use the proper secure idiom: .Pp -.Dl syslog("%s", string); +.Dl syslog(LOG_ERR, "%s", string); diff --git a/gen/syslog.c b/gen/syslog.c index e9af454..216ce85 100644 --- a/gen/syslog.c +++ b/gen/syslog.c @@ -281,7 +281,7 @@ openlog(ident, logstat, logfac) } } if (LogFile != -1 && !connected) - if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { + if (connect(LogFile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) == -1) { (void)close(LogFile); LogFile = -1; } else diff --git a/gen/ulimit.c b/gen/ulimit.c deleted file mode 100644 index af68b84..0000000 --- a/gen/ulimit.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -long int ulimit( int cmd, ... ) -{ - va_list ap; - struct rlimit rlim; - - switch (cmd ) { - case UL_GETFSIZE: - if( getrlimit( RLIMIT_FSIZE, &rlim ) < 0 ) - return -1; - return rlim.rlim_cur/512; - case UL_SETFSIZE: - va_start(ap, cmd); - rlim.rlim_cur = 512 * va_arg(ap, long int); - rlim.rlim_max = rlim.rlim_cur; - va_end(ap); - return setrlimit( RLIMIT_FSIZE, &rlim ); - default: - errno = EINVAL; - return -1; - } - /* NOT REACHED */ - errno = EINVAL; - return -1; -} diff --git a/gen/waitpid.c b/gen/waitpid.c deleted file mode 100644 index 51dd00b..0000000 --- a/gen/waitpid.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include -#include -#include -#include - -pid_t -#if __STDC__ -waitpid(pid_t pid, int *istat, int options) -#else -waitpid(pid, istat, options) - pid_t pid; - int *istat; - int options; -#endif -{ - return (wait4(pid, istat, options, (struct rusage *)0)); -} diff --git a/i386/gen/Makefile.inc b/i386/gen/Makefile.inc index ed150c0..21658c7 100644 --- a/i386/gen/Makefile.inc +++ b/i386/gen/Makefile.inc @@ -1,5 +1,9 @@ -SRCS+= abs.c ecvt.c memcpy.s strcat.c strncat.c \ - bcmp.c ffs.c memmove.s strcmp.c strncmp.c \ - bcopy.s insque.c remque.c strcpy.c strncpy.c \ - bzero.s isinf.c setjmperr.c strlen.c mcount.s \ - bcopy_init.c +SRCS+= bcopy.s \ + bzero.s \ + ecvt.c \ + icacheinval.s \ + isinf.c \ + mcount.s \ + memcpy.s \ + memmove.s \ + setjmperr.c diff --git a/i386/gen/bcopy.s b/i386/gen/bcopy.s index a9910f3..35dbe10 100644 --- a/i386/gen/bcopy.s +++ b/i386/gen/bcopy.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,105 +22,29 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from locore.s. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + +/* + * Call the comm page routines */ +#define __APPLE_API_PRIVATE +#include + #include - /* - * (ov)bcopy (src,dst,cnt) - * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 - */ + TEXT + ALIGN -TEXT -#ifdef MEMCOPY +#if defined(MEMCOPY) LEAF(_memcpy,0) -#else -#ifdef MEMMOVE + movl $(_COMM_PAGE_MEMCPY), %eax + jmpl %eax +#elif defined(MEMMOVE) LEAF(_memmove,0) + movl $(_COMM_PAGE_MEMMOVE), %eax + jmpl %eax #else LEAF(_bcopy,0) + movl $(_COMM_PAGE_BCOPY), %eax + jmpl %eax #endif -#endif - pushl %esi - pushl %edi -#if defined(MEMCOPY) || defined(MEMMOVE) - movl 12(%esp),%edi - movl 16(%esp),%esi -#else - movl 12(%esp),%esi - movl 16(%esp),%edi -#endif - movl 20(%esp),%ecx - movl %edi,%eax - subl %esi,%eax - cmpl %ecx,%eax /* overlapping? */ - jb 1f - cld /* nope, copy forwards. */ - shrl $2,%ecx /* copy by words */ - rep - movsl - movl 20(%esp),%ecx - andl $3,%ecx /* any bytes left? */ - rep - movsb -#if defined(MEMCOPY) || defined(MEMMOVE) - movl 12(%esp),%eax -#endif - popl %edi - popl %esi - ret -1: - addl %ecx,%edi /* copy backwards. */ - addl %ecx,%esi - std - andl $3,%ecx /* any fractional bytes? */ - decl %edi - decl %esi - rep - movsb - movl 20(%esp),%ecx /* copy remainder by words */ - shrl $2,%ecx - subl $3,%esi - subl $3,%edi - rep - movsl -#if defined(MEMCOPY) || defined(MEMMOVE) - movl 12(%esp),%eax -#endif - popl %edi - popl %esi - cld -END(bcopy) diff --git a/i386/gen/bcopy_init.c b/i386/gen/bcopy_init.c deleted file mode 100644 index d10eadc..0000000 --- a/i386/gen/bcopy_init.c +++ /dev/null @@ -1,9 +0,0 @@ -/* Null function. This actually does something on ppc, and this is needed - * for the i386 version to link. - */ -int _cpu_capabilities; - -void _bcopy_initialize() -{ - return; -} diff --git a/i386/gen/bzero.s b/i386/gen/bzero.s index b7953d6..d3cbc5d 100644 --- a/i386/gen/bzero.s +++ b/i386/gen/bzero.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,85 +22,19 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1993 Winning Strategies, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Winning Strategies, Inc. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include /* - * bzero (void *b, size_t len) - * write len zero bytes to the string b. - * - * Written by: - * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + * Call the comm page routine */ -TEXT -LEAF(_bzero,0) - pushl %edi - pushl %ebx - movl 12(%esp),%edi - movl 16(%esp),%ecx - - cld /* set fill direction forward */ - xorl %eax,%eax /* set fill data to 0 */ - - /* - * if the string is too short, it's really not worth the overhead - * of aligning to word boundries, etc. So we jump to a plain - * unaligned set. - */ - cmpl $0x0f,%ecx - jle L1 - - movl %edi,%edx /* compute misalignment */ - negl %edx - andl $3,%edx - movl %ecx,%ebx - subl %edx,%ebx +#define __APPLE_API_PRIVATE +#include - movl %edx,%ecx /* zero until word aligned */ - rep - stosb - - movl %ebx,%ecx /* zero by words */ - shrl $2,%ecx - rep - stosl +#include - movl %ebx,%ecx - andl $3,%ecx /* zero remainder by bytes */ -L1: rep - stosb + TEXT + ALIGN - popl %ebx - popl %edi -END(_bzero) +LEAF(_bzero,0) + movl $(_COMM_PAGE_BZERO), %eax + jmpl %eax diff --git a/i386/gen/icacheinval.s b/i386/gen/icacheinval.s new file mode 100644 index 0000000..d66522d --- /dev/null +++ b/i386/gen/icacheinval.s @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + .text + .align 4, 0x00 + +/* void sys_icache_invalidate(addr_t start, int length) */ +.globl _sys_icache_invalidate +_sys_icache_invalidate: + ret diff --git a/i386/gen/insque.c b/i386/gen/insque.c deleted file mode 100644 index 101daa5..0000000 --- a/i386/gen/insque.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/insque.c - * - * struct qelem { - * struct qelem *q_forw; - * struct qelem *q_back; - * char q_data[]; - * }; - * - * void insque(struct qelem *elem, struct qelem *prev); - * - * Inserts queue entry `elem' into a queue after element `prev'. - * - * HISTORY -* 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) -* Ported to PPC. - * 10-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#include - -void -insque(struct qelem *elem, struct qelem *prev) -{ - struct qelem *next; - - next = prev->q_forw; - prev->q_forw = elem; - if (next != 0) - next->q_back = elem; - elem->q_forw = next; - elem->q_back = prev; -} diff --git a/i386/gen/remque.c b/i386/gen/remque.c deleted file mode 100644 index 380c7f2..0000000 --- a/i386/gen/remque.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/remque.c - * - * struct qelem { - * struct qelem *q_forw; - * struct qelem *q_back; - * char q_data[]; - * }; - * - * void remque(struct qelem *entry); - * - * Removes `entry' from a queue. - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 10-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import - -void -remque(struct qelem *elem) -{ - struct qelem *next, *prev; - - next = elem->q_forw; - prev = elem->q_back; - if (next != 0) - next->q_back = prev; - if (prev != 0) - prev->q_forw = next; -} diff --git a/i386/mach/mach_absolute_time.c b/i386/mach/mach_absolute_time.c index 72d5d29..ffbe0ce 100644 --- a/i386/mach/mach_absolute_time.c +++ b/i386/mach/mach_absolute_time.c @@ -25,12 +25,42 @@ #if !defined(__ppc__) #include #include +#include extern mach_port_t clock_port; -uint64_t mach_absolute_time(void) { - mach_timespec_t now; - (void)clock_get_time(clock_port, &now); - return (uint64_t)now.tv_sec * NSEC_PER_SEC + now.tv_nsec; +inline static uint64_t +fast_get_nano_from_abs(int scale) +{ + uint64_t value; + asm ( + "rdtsc \n\t" + "movl %%edx,%%esi \n\t" + "mull %%ecx \n\t" + "movl %%edx,%%edi \n\t" + "movl %%esi,%%eax \n\t" + "mull %%ecx \n\t" + "xorl %%ecx,%%ecx \n\t" + "addl %%edi,%%eax \n\t" + "adcl %%ecx,%%edx " + : "=A"(value) : "c"(scale) : "%esi", "%edi"); + return value; +} + +uint64_t +mach_absolute_time(void) { + static int scale = 0; + + if (__builtin_expect(scale == 0, 0)) { + mach_timebase_info_data_t info; + mach_timebase_info(&info); + scale = info.numer; + } + if (__builtin_expect(scale == 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 fast_get_nano_from_abs(scale); } #endif diff --git a/i386/pthreads/Makefile.inc b/i386/pthreads/Makefile.inc new file mode 100644 index 0000000..f4f5b0a --- /dev/null +++ b/i386/pthreads/Makefile.inc @@ -0,0 +1,6 @@ +MDSRCS += \ + init_cpu_capabilities.c \ + get_cpu_capabilities.s \ + pthread_set_self.s \ + pthread_self.s \ + pthread_getspecific.s diff --git a/i386/pthreads/get_cpu_capabilities.s b/i386/pthreads/get_cpu_capabilities.s new file mode 100644 index 0000000..8803b6c --- /dev/null +++ b/i386/pthreads/get_cpu_capabilities.s @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* Get the cpu_capabilities bit vector out of the comm page */ + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + +.text +.align 2, 0x90 +.private_extern __get_cpu_capabilities +__get_cpu_capabilities: + movl _COMM_PAGE_CPU_CAPABILITIES, %eax + ret diff --git a/ppc/gen/bcmp.c b/i386/pthreads/init_cpu_capabilities.c similarity index 69% rename from ppc/gen/bcmp.c rename to i386/pthreads/init_cpu_capabilities.c index abdb714..49a7e25 100644 --- a/ppc/gen/bcmp.c +++ b/i386/pthreads/init_cpu_capabilities.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,23 +22,20 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1992, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/bcmp.c - * - * Byte-compare routine. - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - */ -#import +/* Initialize the "_cpu_capabilities" vector on x86 processors. */ + +#define _APPLE_API_PRIVATE +#include +#undef _APPLE_API_PRIVATE + +extern int _get_cpu_capabilities(void); -#undef bcmp +int _cpu_has_altivec = 0; // DEPRECATED +int _cpu_capabilities = 0; -int -bcmp(const void *b1, const void *b2, size_t length) +__private_extern__ void +_init_cpu_capabilities( void ) { - return memcmp(b1, b2, length); + _cpu_capabilities = _get_cpu_capabilities(); } diff --git a/i386/pthreads/pthread_getspecific.s b/i386/pthreads/pthread_getspecific.s new file mode 100644 index 0000000..3c4bf35 --- /dev/null +++ b/i386/pthreads/pthread_getspecific.s @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 _pthread_getspecific +_pthread_getspecific: + movl 4(%esp),%eax + movl %gs:_PTHREAD_TSD_OFFSET(,%eax,4),%eax + ret diff --git a/ppc/sys/ur_cthread.s b/i386/pthreads/pthread_self.s similarity index 85% rename from ppc/sys/ur_cthread.s rename to i386/pthreads/pthread_self.s index 8cbd330..8e2bace 100644 --- a/ppc/sys/ur_cthread.s +++ b/i386/pthreads/pthread_self.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,10 +22,12 @@ * * @APPLE_LICENSE_HEADER_END@ */ - .text - .align 2 - .globl _pthread_self + +#include "pthread_machdep.h" + +.text +.align 2, 0x90 +.globl _pthread_self _pthread_self: - li r0, 0x7FF2 - sc - blr + movl %gs:_PTHREAD_TSD_OFFSET,%eax + ret diff --git a/i386/pthreads/pthread_set_self.s b/i386/pthreads/pthread_set_self.s new file mode 100644 index 0000000..6d51d1d --- /dev/null +++ b/i386/pthreads/pthread_set_self.s @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +.text +.align 2, 0x90 +.globl ___pthread_set_self +___pthread_set_self: + pushl 4(%esp) + pushl $0 + movl $3,%eax + lcall $0x3b,$0 + addl $8,%esp + movw %ax,%gs + ret diff --git a/i386/stdlib/gdtoa.mk b/i386/stdlib/gdtoa.mk new file mode 100644 index 0000000..6a6a67d --- /dev/null +++ b/i386/stdlib/gdtoa.mk @@ -0,0 +1,2 @@ +# Long double is 80 bits +FBSDSRCS+=gdtoa_strtopx.c machdep_ldisx.c diff --git a/i386/string/Makefile.inc b/i386/string/Makefile.inc new file mode 100644 index 0000000..e8b30d7 --- /dev/null +++ b/i386/string/Makefile.inc @@ -0,0 +1,11 @@ +# $Version$ +# +# i386-optimised string functions. +# +# +# +#MDSRCS += \ +# strcmp.s + + + diff --git a/string/strcmp.s b/i386/string/strcmp.s similarity index 92% rename from string/strcmp.s rename to i386/string/strcmp.s index 94c82b1..781f6de 100644 --- a/string/strcmp.s +++ b/i386/string/strcmp.s @@ -25,7 +25,6 @@ .text .globl _strcmp _strcmp: -#if defined(__i386__) movl 0x04(%esp),%eax movl 0x08(%esp),%edx jmp L2 /* Jump into the loop! */ @@ -92,17 +91,3 @@ L3: movzbl (%eax),%eax /* unsigned comparison */ movzbl (%edx),%edx subl %edx,%eax ret -#elif defined(__ppc__) - mr r5,r3 -1: lbz r3,0(r5) - addi r5,r5,1 - cmpwi cr1,r3,0 - lbz r0,0(r4) - addi r4,r4,1 - subf. r3,r0,r3 - beqlr+ cr1 - beq- 1b - blr -#else -#error strcmp is not defined for this architecture -#endif diff --git a/i386/sys/Makefile.inc b/i386/sys/Makefile.inc index 1d046d1..53e8049 100644 --- a/i386/sys/Makefile.inc +++ b/i386/sys/Makefile.inc @@ -16,6 +16,17 @@ SRCS+= ATPgetreq.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 \ + auditsvc.s \ bind.s \ cerror.s \ chdir.s \ @@ -35,9 +46,11 @@ SRCS+= ATPgetreq.s \ fchmod.s \ fchown.s \ fcntl.s \ + fhopen.s \ flock.s \ fork.s \ fpathconf.s \ + fsctl.s \ fstat.s \ fstatfs.s \ fstatv.s \ @@ -45,6 +58,9 @@ SRCS+= ATPgetreq.s \ ftruncate.s \ futimes.s \ getattrlist.s \ + getaudit.s \ + getaudit_addr.s \ + getauid.s \ getdirentries.s \ getdirentriesattr.s \ getegid.s \ @@ -68,9 +84,14 @@ SRCS+= ATPgetreq.s \ getuid.s \ ioctl.s \ issetugid.s \ + kevent.s \ kill.s \ + kqueue.s \ + kqueue_from_portset_np.s \ + kqueue_portset_np.s \ ktrace.s \ link.s \ + lio_listio.s \ listen.s \ load_shared_file.s \ lseek.s \ @@ -98,6 +119,7 @@ SRCS+= ATPgetreq.s \ munlockall.s \ munmap.s \ new_system_shared_regions.s \ + nfsclnt.s \ nfssvc.s \ open.s \ pathconf.s \ @@ -126,10 +148,8 @@ SRCS+= ATPgetreq.s \ sem_destroy.s \ sem_getvalue.s \ sem_init.s \ - sem_open.s \ sem_post.s \ sem_trywait.s \ - sem_unlink.s \ sem_wait.s \ semconfig.s \ semctl.s \ @@ -139,6 +159,9 @@ SRCS+= ATPgetreq.s \ sendmsg.s \ sendto.s \ setattrlist.s \ + setaudit.s \ + setaudit_addr.s \ + setauid.s \ setegid.s \ seteuid.s \ setgid.s \ @@ -154,8 +177,6 @@ SRCS+= ATPgetreq.s \ setsockopt.s \ settimeofday.s \ setuid.s \ - shm_open.s \ - shm_unlink.s \ shmat.s \ shmctl.s \ shmdt.s \ diff --git a/i386/sys/sem_unlink.s b/i386/sys/aio_cancel.s similarity index 91% rename from i386/sys/sem_unlink.s rename to i386/sys/aio_cancel.s index 815eaf9..1f42173 100644 --- a/i386/sys/sem_unlink.s +++ b/i386/sys/aio_cancel.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,6 +24,5 @@ */ #include "SYS.h" -UNIX_SYSCALL(sem_unlink, 1) +UNIX_SYSCALL(aio_cancel, 2) ret - diff --git a/i386/sys/sem_open.s b/i386/sys/aio_error.s similarity index 91% rename from i386/sys/sem_open.s rename to i386/sys/aio_error.s index 92d7817..ca41605 100644 --- a/i386/sys/sem_open.s +++ b/i386/sys/aio_error.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,6 +24,5 @@ */ #include "SYS.h" -UNIX_SYSCALL(sem_open, 4) +UNIX_SYSCALL(aio_error, 1) ret - diff --git a/i386/sys/aio_fsync.s b/i386/sys/aio_fsync.s new file mode 100644 index 0000000..3d12301 --- /dev/null +++ b/i386/sys/aio_fsync.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(aio_fsync, 2) + ret diff --git a/i386/sys/aio_read.s b/i386/sys/aio_read.s new file mode 100644 index 0000000..a34702d --- /dev/null +++ b/i386/sys/aio_read.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(aio_read, 1) + ret diff --git a/i386/sys/aio_return.s b/i386/sys/aio_return.s new file mode 100644 index 0000000..ebe1885 --- /dev/null +++ b/i386/sys/aio_return.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(aio_return, 1) + ret diff --git a/i386/sys/aio_suspend.s b/i386/sys/aio_suspend.s new file mode 100644 index 0000000..6654fff --- /dev/null +++ b/i386/sys/aio_suspend.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(aio_suspend, 3) + ret \ No newline at end of file diff --git a/i386/sys/aio_write.s b/i386/sys/aio_write.s new file mode 100644 index 0000000..66c5c20 --- /dev/null +++ b/i386/sys/aio_write.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(aio_write, 1) + ret \ No newline at end of file diff --git a/i386/sys/audit.s b/i386/sys/audit.s new file mode 100644 index 0000000..3bb8e84 --- /dev/null +++ b/i386/sys/audit.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(audit, 2) + ret diff --git a/i386/sys/auditctl.s b/i386/sys/auditctl.s new file mode 100644 index 0000000..5fea33a --- /dev/null +++ b/i386/sys/auditctl.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(auditctl, 1) + ret diff --git a/i386/sys/auditon.s b/i386/sys/auditon.s new file mode 100644 index 0000000..33b9334 --- /dev/null +++ b/i386/sys/auditon.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(auditon, 3) + ret diff --git a/i386/sys/auditsvc.s b/i386/sys/auditsvc.s new file mode 100644 index 0000000..83c3017 --- /dev/null +++ b/i386/sys/auditsvc.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(auditsvc, 2) + ret diff --git a/i386/sys/fhopen.s b/i386/sys/fhopen.s new file mode 100644 index 0000000..c886e3c --- /dev/null +++ b/i386/sys/fhopen.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(fhopen, 2) + ret diff --git a/i386/sys/fork.s b/i386/sys/fork.s index 8eecc9a..54badfd 100644 --- a/i386/sys/fork.s +++ b/i386/sys/fork.s @@ -118,7 +118,8 @@ LC0: addl $4,%esp // deallocate the space for the address param call *%eax // call __dyld_fork_child indirectly #endif - CALL_EXTERN(_fork_mach_init) + xorl %eax, %eax + REG_TO_EXTERN(%eax, __current_pid) CALL_EXTERN(__cthread_fork_child) #if defined(__DYNAMIC__) .cstring diff --git a/i386/sys/shm_open.s b/i386/sys/fsctl.s similarity index 92% rename from i386/sys/shm_open.s rename to i386/sys/fsctl.s index bd8f6c7..282d100 100644 --- a/i386/sys/shm_open.s +++ b/i386/sys/fsctl.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -27,5 +27,5 @@ */ #include "SYS.h" -UNIX_SYSCALL(shm_open, 3) +UNIX_SYSCALL(fsctl, 4) ret diff --git a/i386/sys/getaudit.s b/i386/sys/getaudit.s new file mode 100644 index 0000000..9d9abb3 --- /dev/null +++ b/i386/sys/getaudit.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(getaudit, 1) + ret diff --git a/i386/sys/getaudit_addr.s b/i386/sys/getaudit_addr.s new file mode 100644 index 0000000..aa74b66 --- /dev/null +++ b/i386/sys/getaudit_addr.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(getaudit_addr, 2) + ret diff --git a/i386/sys/getauid.s b/i386/sys/getauid.s new file mode 100644 index 0000000..e6b069e --- /dev/null +++ b/i386/sys/getauid.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(getauid, 1) + ret diff --git a/i386/sys/getpid.s b/i386/sys/getpid.s index 81833ae..5e75fc2 100644 --- a/i386/sys/getpid.s +++ b/i386/sys/getpid.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -27,5 +27,41 @@ */ #include "SYS.h" -UNIX_SYSCALL(getpid, 0) - ret // pid = getpid(); + .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 + lock + cmpxchgl %edx, __current_pid + movl %edx, %eax + ret diff --git a/i386/sys/kevent.s b/i386/sys/kevent.s new file mode 100644 index 0000000..0470823 --- /dev/null +++ b/i386/sys/kevent.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(kevent, 6) + ret diff --git a/i386/sys/kqueue.s b/i386/sys/kqueue.s new file mode 100644 index 0000000..044c690 --- /dev/null +++ b/i386/sys/kqueue.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(kqueue, 0) + ret diff --git a/i386/sys/kqueue_from_portset_np.s b/i386/sys/kqueue_from_portset_np.s new file mode 100644 index 0000000..c44cc2b --- /dev/null +++ b/i386/sys/kqueue_from_portset_np.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(kqueue_from_portset_np, 1) + ret diff --git a/i386/sys/kqueue_portset_np.s b/i386/sys/kqueue_portset_np.s new file mode 100644 index 0000000..a61c9c0 --- /dev/null +++ b/i386/sys/kqueue_portset_np.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(kqueue_portset_np, 1) + ret diff --git a/i386/sys/lio_listio.s b/i386/sys/lio_listio.s new file mode 100644 index 0000000..468c378 --- /dev/null +++ b/i386/sys/lio_listio.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(lio_listio, 4) + ret diff --git a/i386/sys/msync.s b/i386/sys/msync.s index b20da30..1bae397 100644 --- a/i386/sys/msync.s +++ b/i386/sys/msync.s @@ -27,5 +27,5 @@ */ #include "SYS.h" -UNIX_SYSCALL(msync, 2) +UNIX_SYSCALL(msync, 3) ret diff --git a/i386/sys/nfsclnt.s b/i386/sys/nfsclnt.s new file mode 100644 index 0000000..0e24250 --- /dev/null +++ b/i386/sys/nfsclnt.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(nfsclnt, 2) + ret diff --git a/i386/sys/setaudit.s b/i386/sys/setaudit.s new file mode 100644 index 0000000..305af1b --- /dev/null +++ b/i386/sys/setaudit.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(setaudit, 1) + ret diff --git a/i386/sys/setaudit_addr.s b/i386/sys/setaudit_addr.s new file mode 100644 index 0000000..4dc6e6a --- /dev/null +++ b/i386/sys/setaudit_addr.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(setaudit_addr, 2) + ret diff --git a/i386/sys/setauid.s b/i386/sys/setauid.s new file mode 100644 index 0000000..234fe56 --- /dev/null +++ b/i386/sys/setauid.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +UNIX_SYSCALL(setauid, 1) + ret diff --git a/i386/sys/vfork.s b/i386/sys/vfork.s index c9375b4..266b7d1 100644 --- a/i386/sys/vfork.s +++ b/i386/sys/vfork.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -27,162 +27,49 @@ */ #include "SYS.h" -#if 0 -LEAF(_vfork, 0) - 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 - subl $4,%esp // allocate space for the address parameter - leal 0(%esp),%eax // get the address of the allocated space - pushl %eax // push the address of the allocated space - call 1f -1: popl %eax - leal LC1-1b(%eax),%eax - pushl %eax // push the name of the function to look up - call __dyld_func_lookup - addl $8,%esp // remove parameters to __dyld_func_lookup - movl 0(%esp),%eax // move the value returned in address parameter - addl $4,%esp // deallocate the space for the address param - call *%eax // call __dyld_fork_prepare indirectly -#endif - - movl $ SYS_vfork,%eax; // code for vfork -> 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 vfork syscall. -// This releases the dyld lock acquired by __dyld_fork_prepare(). In this case -// we just use it to clean up after a vfork error so the parent process can -// dyld after vfork() errors without deadlocking. -.cstring -LC2: - .ascii "__dyld_fork_parent\0" -.text - pushl %eax // save the return value (errno) - subl $4,%esp // allocate space for the address parameter - leal 0(%esp),%eax // get the address of the allocated space - pushl %eax // push the address of the allocated space - call 1f -1: popl %eax - leal LC2-1b(%eax),%eax - pushl %eax // push the name of the function to look up - call __dyld_func_lookup - addl $8,%esp // remove parameters to __dyld_func_lookup - movl 0(%esp),%eax // move the value returned in address parameter - addl $4,%esp // deallocate the space for the address param - call *%eax // call __dyld_fork_parent indirectly - popl %eax // restore the return value (errno) -#endif - CALL_EXTERN(cerror) - CALL_EXTERN(__cthread_fork_parent) - movl $-1,%eax - 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 vfork we need to tell the dynamic linker that -// we have vforked. To do this we call __dyld_fork_child in the dyanmic -// linker. But since we can't dynamicly 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 - subl $4,%esp // allocate space for the address parameter - leal 0(%esp),%eax // get the address of the allocated space - pushl %eax // push the address of the allocated space - call 1f -1: popl %eax - leal LC0-1b(%eax),%eax - pushl %eax // push the name of the function to look up - call __dyld_func_lookup - addl $8,%esp // remove parameters to __dyld_func_lookup - movl 0(%esp),%eax // move the value returned in address parameter - addl $4,%esp // deallocate the space for the address param - call *%eax // call __dyld_fork_child indirectly -#endif - CALL_EXTERN(_fork_mach_init) - CALL_EXTERN(__cthread_fork_child) -#if defined(__DYNAMIC__) -.cstring -LC10: - .ascii "__dyld_fork_child_final\0" +#define GET_CURRENT_PID PICIFY(__current_pid) -.text - subl $4,%esp // allocate space for the address parameter - leal 0(%esp),%eax // get the address of the allocated space - pushl %eax // push the address of the allocated space - call 1f -1: popl %eax - leal LC10-1b(%eax),%eax - pushl %eax // push the name of the function to look up - call __dyld_func_lookup - addl $8,%esp // remove parameters to __dyld_func_lookup - movl 0(%esp),%eax // move the value returned in address parameter - addl $4,%esp // deallocate the space for the address param - call *%eax // call __dyld_fork_child_final indirectly + NON_LAZY_STUB(__current_pid) +#define __current_pid (%edx) +#else +#define GET_CURRENT_PID #endif - xorl %eax,%eax // zero eax - ret - //parent here... -L2: - push %eax // save pid -#if defined(__DYNAMIC__) -// __dyld_fork_parent() is called by the parent process after a vfork syscall. -// This releases the dyld lock acquired by __dyld_fork_prepare(). - subl $4,%esp // allocate space for the address parameter - leal 0(%esp),%eax // get the address of the allocated space - pushl %eax // push the address of the allocated space - call 1f -1: popl %eax - leal LC2-1b(%eax),%eax - pushl %eax // push the name of the function to look up - call __dyld_func_lookup - addl $8,%esp // remove parameters to __dyld_func_lookup - movl 0(%esp),%eax // move the value returned in address parameter - addl $4,%esp // deallocate the space for the address param - call *%eax // call __dyld_fork_parent indirectly -#endif - CALL_EXTERN_AGAIN(__cthread_fork_parent) - pop %eax - ret -#else +/* + * If __current_pid >= 0, we want to put a -1 in there + * otherwise we just decrement it + */ LEAF(_vfork, 0) - popl %ecx - movl $ SYS_vfork,%eax; // code for vfork -> eax - UNIX_SYSCALL_TRAP; // do the system call - jnb L1 // jump if CF==0 - pushl %ecx - BRANCH_EXTERN(cerror) + 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: - orl %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 + 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: - jmp *%ecx - -#endif - + GET_CURRENT_PID + lock + incl __current_pid + jmp *%ecx diff --git a/i386/threads/Makefile.inc b/i386/threads/Makefile.inc deleted file mode 100644 index b0e854d..0000000 --- a/i386/threads/Makefile.inc +++ /dev/null @@ -1,2 +0,0 @@ -CFLAGS+= -I${.CURDIR}/threads -SRCS+= thread.c diff --git a/include/Makefile.inc b/include/Makefile.inc index f6eb88b..cd3a7df 100644 --- a/include/Makefile.inc +++ b/include/Makefile.inc @@ -1,70 +1,85 @@ .include "${.CURDIR}/include/arpa/Makefile.inc" .include "${.CURDIR}/include/protocols/Makefile.inc" +.include "${.CURDIR}/include/malloc/Makefile.inc" .include "${.CURDIR}/include/objc/Makefile.inc" +# waiting for 2852915 to be reviewed/approved +# alloca.h INC_INSTHDRS += NSSystemDirectories.h \ - ar.h \ - asm.h \ - bitstring.h \ - c.h \ - crt_externs.h \ - ctype.h \ - db.h \ - dirent.h \ - disktab.h \ - err.h \ - errno.h \ - fcntl.h \ - fnmatch.h \ - fsproperties.h \ - fstab.h \ - fts.h \ - glob.h \ - grp.h \ - kvm.h \ - libc.h \ - libgen.h \ - limits.h \ - locale.h \ - memory.h \ - monitor.h \ - mpool.h \ - ndbm.h \ - netdb.h \ - nlist.h \ - paths.h \ - pwd.h \ - ranlib.h \ - regex.h \ - regexp.h \ - rune.h \ - runetype.h \ - semaphore.h \ - setjmp.h \ - sgtty.h \ - signal.h \ - stab.h \ - standards.h \ - stddef.h \ - stdio.h \ - stdlib.h \ - string.h \ - strings.h \ - struct.h \ - sysexits.h \ - syslog.h \ - tar.h \ - termios.h \ - time.h \ - ttyent.h \ - tzfile.h \ - ucontext.h \ - ulimit.h \ - unistd.h \ - util.h \ - utime.h \ - utmp.h \ - vis.h \ + alloca.h \ + ar.h \ + asm.h \ + bitstring.h \ + c.h \ + crt_externs.h \ + ctype.h \ + db.h \ + dirent.h \ + disktab.h \ + err.h \ + errno.h \ + fcntl.h \ + fnmatch.h \ + fsproperties.h \ + fstab.h \ + fts.h \ + getopt.h \ + glob.h \ + grp.h \ + iso646.h \ + kvm.h \ + langinfo.h \ + libc.h \ + libgen.h \ + limits.h \ + locale.h \ + memory.h \ + monetary.h \ + monitor.h \ + mpool.h \ + ndbm.h \ + nl_types.h \ + nlist.h \ + paths.h \ + pwd.h \ + ranlib.h \ + readpassphrase.h \ + regex.h \ + regexp.h \ + rune.h \ + runetype.h \ + search.h \ + semaphore.h \ + setjmp.h \ + sgtty.h \ + signal.h \ + stab.h \ + standards.h \ + stddef.h \ + stdio.h \ + stdlib.h \ + strhash.h \ + string.h \ + stringlist.h \ + strings.h \ + struct.h \ + sysexits.h \ + syslog.h \ + tar.h \ + termios.h \ + time.h \ + timeconv.h \ + ttyent.h \ + tzfile.h \ + ucontext.h \ + ulimit.h \ + unistd.h \ + util.h \ + utime.h \ + utmp.h \ + vis.h \ + wchar.h \ + wctype.h INC_INSTHDRS := ${INC_INSTHDRS:S/^/${.CURDIR}\/include\//} INSTHDRS += ${INC_INSTHDRS} diff --git a/include/NSSystemDirectories.h b/include/NSSystemDirectories.h index 1314a1a..83938a9 100644 --- a/include/NSSystemDirectories.h +++ b/include/NSSystemDirectories.h @@ -50,6 +50,10 @@ #ifndef __NS_SYSTEM_DIRECTORIES_H__ #define __NS_SYSTEM_DIRECTORIES_H__ +#ifdef __cplusplus +extern "C" { +#endif + // Directories typedef enum { @@ -84,8 +88,13 @@ typedef unsigned int NSSearchPathEnumerationState; The return value of NSGetNextSearchPathEnumeration() should be used as the state next time around. When NSGetNextSearchPathEnumeration() returns 0, you're done. */ + extern NSSearchPathEnumerationState NSStartSearchPathEnumeration(NSSearchPathDirectory dir, NSSearchPathDomainMask domainMask); extern NSSearchPathEnumerationState NSGetNextSearchPathEnumeration(NSSearchPathEnumerationState state, char *path); +#ifdef __cplusplus +} +#endif + #endif /* __NS_SYSTEM_DIRECTORIES_H__ */ diff --git a/string/rindix.c b/include/aio.h similarity index 77% rename from string/rindix.c rename to include/aio.h index 0307fc2..2221454 100644 --- a/string/rindix.c +++ b/include/aio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,19 +22,18 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. +/* + * File: aio.h + * Author: Umesh Vaishampayan [umeshv@apple.com] + * 05-Feb-2003 umeshv Created. * - * File: libc/string/rindex.c - */ - -#import - -#undef rindex - -char *rindex(const char *s, int c) -{ - return strrchr(s, c); -} + * Header file for POSIX Asynchronous IO APIs + * + */ +#ifndef _AIO_H_ +#define _AIO_H_ +#include +#endif /* _AIO_H_ */ diff --git a/string/strchr.c b/include/alloca.h similarity index 65% rename from string/strchr.c rename to include/alloca.h index 144b45d..ef101c4 100644 --- a/string/strchr.c +++ b/include/alloca.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,26 +22,28 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/string/strchr.c - * - * This file contains machine independent code for string index - * - * HISTORY - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import -/* This routine needs to be optimized. */ +#ifndef _ALLOCA_H_ +#define _ALLOCA_H_ + +#include +#include + +#ifndef _BSD_SIZE_T_DEFINED_ +#define _BSD_SIZE_T_DEFINED_ +typedef _BSD_SIZE_T_ size_t; +#endif + +__BEGIN_DECLS +void *alloca(size_t); /* built-in for gcc */ +__END_DECLS -char *strchr(const char *s, int c) -{ - const char ch = c; +#if defined(__GNUC__) && __GNUC__ >= 3 +/* built-in for gcc 3 */ +#undef alloca +#undef __alloca +#define alloca(size) __alloca(size) +#define __alloca(size) __builtin_alloca(size) +#endif - for ( ; *s != ch; s++) - if (*s == '\0') - return 0; - return (char *)s; -} +#endif /* _ALLOCA_H_ */ diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h index ea310c8..b794bda 100644 --- a/include/arpa/tftp.h +++ b/include/arpa/tftp.h @@ -75,10 +75,10 @@ #define ERROR 05 /* error code */ struct tftphdr { - short th_opcode; /* packet type */ + unsigned short th_opcode; /* packet type */ union { - short tu_block; /* block # */ - short tu_code; /* error code */ + unsigned short tu_block; /* block # */ + unsigned short tu_code; /* error code */ char tu_stuff[1]; /* request packet stuff */ } th_u; char th_data[1]; /* data or error string */ diff --git a/include/authentication.h b/include/authentication.h index 31ae0be..8f8b055 100644 --- a/include/authentication.h +++ b/include/authentication.h @@ -26,9 +26,13 @@ #ifndef __AUTHENTICATION_H__ #define __AUTHENTICATION_H__ +#include + +__BEGIN_DECLS extern char *groupNameForTask(int taskNum); extern int isAuthenticatedAsAdministrator(void); extern int isAuthenticatedAsAdministratorForTask(int taskNum); extern int isAuthenticatedAsRoot(void); +__END_DECLS #endif /* __AUTHENTICATION_H__ */ diff --git a/include/crt_externs.h b/include/crt_externs.h index af46a2b..b27150f 100644 --- a/include/crt_externs.h +++ b/include/crt_externs.h @@ -33,8 +33,12 @@ ** AOF (afreier@next.com) */ +#include + +__BEGIN_DECLS extern char ***_NSGetArgv(void); extern int *_NSGetArgc(void); extern char ***_NSGetEnviron(void); extern char **_NSGetProgname(void); extern struct mach_header *_NSGetMachExecuteHeader(void); +__END_DECLS diff --git a/include/ctype.h b/include/ctype.h index bd0bc36..a8167ec 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -70,98 +70,109 @@ #include -#define _A 0x00000100L /* Alpha */ -#define _C 0x00000200L /* Control */ -#define _D 0x00000400L /* Digit */ -#define _G 0x00000800L /* Graph */ -#define _L 0x00001000L /* Lower */ -#define _P 0x00002000L /* Punct */ -#define _S 0x00004000L /* Space */ -#define _U 0x00008000L /* Upper */ -#define _X 0x00010000L /* X digit */ -#define _B 0x00020000L /* Blank */ -#define _R 0x00040000L /* Print */ -#define _I 0x00080000L /* Ideogram */ -#define _T 0x00100000L /* Special */ -#define _Q 0x00200000L /* Phonogram */ - -#define _CTYPE_A _A -#define _CTYPE_C _C -#define _CTYPE_D _D -#define _CTYPE_G _G -#define _CTYPE_L _L -#define _CTYPE_P _P -#define _CTYPE_S _S -#define _CTYPE_U _U -#define _CTYPE_X _X -#define _CTYPE_B _B -#define _CTYPE_R _R -#define _CTYPE_I _I -#define _CTYPE_T _T -#define _CTYPE_Q _Q +#define _CTYPE_A 0x00000100L /* Alpha */ +#define _CTYPE_C 0x00000200L /* Control */ +#define _CTYPE_D 0x00000400L /* Digit */ +#define _CTYPE_G 0x00000800L /* Graph */ +#define _CTYPE_L 0x00001000L /* Lower */ +#define _CTYPE_P 0x00002000L /* Punct */ +#define _CTYPE_S 0x00004000L /* Space */ +#define _CTYPE_U 0x00008000L /* Upper */ +#define _CTYPE_X 0x00010000L /* X digit */ +#define _CTYPE_B 0x00020000L /* Blank */ +#define _CTYPE_R 0x00040000L /* Print */ +#define _CTYPE_I 0x00080000L /* Ideogram */ +#define _CTYPE_T 0x00100000L /* Special */ +#define _CTYPE_Q 0x00200000L /* Phonogram */ +#define _CTYPE_SW0 0x20000000L /* 0 width character */ +#define _CTYPE_SW1 0x40000000L /* 1 width character */ +#define _CTYPE_SW2 0x80000000L /* 2 width character */ +#define _CTYPE_SW3 0xc0000000L /* 3 width character */ + +/* + * Backward compatibility + */ +#define _A _CTYPE_A /* Alpha */ +#define _C _CTYPE_C /* Control */ +#define _D _CTYPE_D /* Digit */ +#define _G _CTYPE_G /* Graph */ +#define _L _CTYPE_L /* Lower */ +#define _P _CTYPE_P /* Punct */ +#define _S _CTYPE_S /* Space */ +#define _U _CTYPE_U /* Upper */ +#define _X _CTYPE_X /* X digit */ +#define _B _CTYPE_B /* Blank */ +#define _R _CTYPE_R /* Print */ +#define _I _CTYPE_I /* Ideogram */ +#define _T _CTYPE_T /* Special */ +#define _Q _CTYPE_Q /* Phonogram */ +#define _SW0 _CTYPE_SW0 /* 0 width character */ +#define _SW1 _CTYPE_SW1 /* 1 width character */ +#define _SW2 _CTYPE_SW2 /* 2 width character */ +#define _SW3 _CTYPE_SW3 /* 3 width character */ __BEGIN_DECLS -int isalnum __P((int)); -int isalpha __P((int)); -int iscntrl __P((int)); -int isdigit __P((int)); -int isgraph __P((int)); -int islower __P((int)); -int isprint __P((int)); -int ispunct __P((int)); -int isspace __P((int)); -int isupper __P((int)); -int isxdigit __P((int)); -int tolower __P((int)); -int toupper __P((int)); +int isalnum(int); +int isalpha(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); #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) -int digittoint __P((int)); -int isascii __P((int)); -int isblank __P((int)); -int ishexnumber __P((int)); -int isideogram __P((int)); -int isnumber __P((int)); -int isphonogram __P((int)); -int isrune __P((int)); -int isspecial __P((int)); -int toascii __P((int)); +int digittoint(int); +int isascii(int); +int isblank(int); +int ishexnumber(int); +int isideogram(int); +int isnumber(int); +int isphonogram(int); +int isrune(int); +int isspecial(int); +int toascii(int); #endif __END_DECLS -#define isalnum(c) __istype((c), (_A|_D)) -#define isalpha(c) __istype((c), _A) -#define iscntrl(c) __istype((c), _C) -#define isdigit(c) __isctype((c), _D) /* ANSI -- locale independent */ -#define isgraph(c) __istype((c), _G) -#define islower(c) __istype((c), _L) -#define isprint(c) __istype((c), _R) -#define ispunct(c) __istype((c), _P) -#define isspace(c) __istype((c), _S) -#define isupper(c) __istype((c), _U) -#define isxdigit(c) __isctype((c), _X) /* ANSI -- locale independent */ +#define isalnum(c) __istype((c), (_CTYPE_A|_CTYPE_D)) +#define isalpha(c) __istype((c), _CTYPE_A) +#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) #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) #define digittoint(c) __maskrune((c), 0xFF) #define isascii(c) ((c & ~0x7F) == 0) -#define isblank(c) __istype((c), _B) -#define ishexnumber(c) __istype((c), _X) -#define isideogram(c) __istype((c), _I) -#define isnumber(c) __istype((c), _D) -#define isphonogram(c) __istype((c), _T) +#define isblank(c) __istype((c), _CTYPE_B) +#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), _Q) +#define isspecial(c) __istype((c), _CTYPE_T) #define toascii(c) ((c) & 0x7F) #endif /* See comments in about _BSD_RUNE_T_. */ __BEGIN_DECLS -unsigned long ___runetype __P((_BSD_CT_RUNE_T_)); -_BSD_CT_RUNE_T_ ___tolower __P((_BSD_CT_RUNE_T_)); -_BSD_CT_RUNE_T_ ___toupper __P((_BSD_CT_RUNE_T_)); +unsigned long ___runetype(_BSD_CT_RUNE_T_); +_BSD_CT_RUNE_T_ ___tolower(_BSD_CT_RUNE_T_); +_BSD_CT_RUNE_T_ ___toupper(_BSD_CT_RUNE_T_); __END_DECLS /* @@ -217,11 +228,11 @@ __tolower(_BSD_CT_RUNE_T_ _c) #else /* not using inlines */ __BEGIN_DECLS -int __maskrune __P((_BSD_CT_RUNE_T_, unsigned long)); -int __istype __P((_BSD_CT_RUNE_T_, unsigned long)); -int __isctype __P((_BSD_CT_RUNE_T_, unsigned long)); -_BSD_CT_RUNE_T_ __toupper __P((_BSD_CT_RUNE_T_)); -_BSD_CT_RUNE_T_ __tolower __P((_BSD_CT_RUNE_T_)); +int __maskrune(_BSD_CT_RUNE_T_, unsigned long); +int __istype (_BSD_CT_RUNE_T_, unsigned long); +int __isctype(_BSD_CT_RUNE_T_, unsigned long); +_BSD_CT_RUNE_T_ __toupper(_BSD_CT_RUNE_T_); +_BSD_CT_RUNE_T_ __tolower(_BSD_CT_RUNE_T_); __END_DECLS #endif /* using inlines */ diff --git a/include/db.h b/include/db.h index 160f8cb..bd1eb9f 100644 --- a/include/db.h +++ b/include/db.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,7 @@ * @APPLE_LICENSE_HEADER_END@ */ /*- - * Copyright (c) 1990, 1993 + * 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 @@ -54,7 +54,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)db.h 8.4 (Berkeley) 2/21/94 + * @(#)db.h 8.7 (Berkeley) 6/16/94 + * $FreeBSD: src/include/db.h,v 1.5 2002/03/26 01:35:05 bde Exp $ */ #ifndef _DB_H_ @@ -123,14 +124,14 @@ typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; /* Access method description structure. */ typedef struct __db { DBTYPE type; /* Underlying db type. */ - int (*close) __P((struct __db *)); - int (*del) __P((const struct __db *, const DBT *, u_int)); - int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); - int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); - int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); - int (*sync) __P((const struct __db *, u_int)); + int (*close)(struct __db *); + int (*del)(const struct __db *, const DBT *, u_int); + int (*get)(const struct __db *, const DBT *, DBT *, u_int); + int (*put)(const struct __db *, DBT *, const DBT *, u_int); + int (*seq)(const struct __db *, DBT *, DBT *, u_int); + int (*sync)(const struct __db *, u_int); void *internal; /* Access method private. */ - int (*fd) __P((const struct __db *)); + int (*fd)(const struct __db *); } DB; #define BTREEMAGIC 0x053162 @@ -145,9 +146,9 @@ typedef struct { int minkeypage; /* minimum keys per page */ u_int psize; /* page size */ int (*compare) /* comparison function */ - __P((const DBT *, const DBT *)); + (const DBT *, const DBT *); size_t (*prefix) /* prefix function */ - __P((const DBT *, const DBT *)); + (const DBT *, const DBT *); int lorder; /* byte order */ } BTREEINFO; @@ -161,7 +162,7 @@ typedef struct { u_int nelem; /* number of elements */ u_int cachesize; /* bytes to cache */ u_int32_t /* hash function */ - (*hash) __P((const void *, size_t)); + (*hash)(const void *, size_t); int lorder; /* byte order */ } HASHINFO; @@ -230,13 +231,13 @@ typedef struct { #endif __BEGIN_DECLS -DB *dbopen __P((const char *, int, int, DBTYPE, const void *)); +DB *dbopen(const char *, int, int, DBTYPE, const void *); #ifdef __DBINTERFACE_PRIVATE -DB *__bt_open __P((const char *, int, int, const BTREEINFO *, int)); -DB *__hash_open __P((const char *, int, int, const HASHINFO *, int)); -DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int)); -void __dbpanic __P((DB *dbp)); +DB *__bt_open(const char *, int, int, const BTREEINFO *, int); +DB *__hash_open(const char *, int, int, const HASHINFO *, int); +DB *__rec_open(const char *, int, int, const RECNOINFO *, int); +void __dbpanic(DB *dbp); #endif __END_DECLS #endif /* !_DB_H_ */ diff --git a/include/dirent.h b/include/dirent.h index af819d4..ecdc13e 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -64,6 +64,7 @@ * The kernel defines the format of directory entries returned by * the getdirentries(2) system call. */ +#include #include #ifdef _POSIX_SOURCE @@ -75,6 +76,8 @@ typedef void * DIR; /* definitions for library routines operating on directories. */ #define DIRBLKSIZ 1024 +struct _telldir; /* see telldir.h */ + /* structure describing an open directory. */ typedef struct _dirdesc { int dd_fd; /* file descriptor associated with directory */ @@ -85,6 +88,8 @@ typedef struct _dirdesc { long dd_seek; /* magic cookie returned by getdirentries */ long dd_rewind; /* magic cookie for rewinding */ int dd_flags; /* flags for readdir */ + pthread_mutex_t dd_lock; /* for thread locking */ + struct _telldir *dd_td; /* telldir position recording */ } DIR; #define dirfd(dirp) ((dirp)->dd_fd) @@ -106,19 +111,19 @@ typedef struct _dirdesc { #include __BEGIN_DECLS -DIR *opendir __P((const char *)); -struct dirent *readdir __P((DIR *)); -void rewinddir __P((DIR *)); -int closedir __P((DIR *)); +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +void rewinddir(DIR *); +int closedir(DIR *); #ifndef _POSIX_SOURCE -DIR *__opendir2 __P((const char *, int)); -long telldir __P((const DIR *)); -void seekdir __P((DIR *, long)); -int scandir __P((const char *, struct dirent ***, - int (*)(struct dirent *), int (*)(const void *, const void *))); -int alphasort __P((const void *, const void *)); -int getdirentries __P((int, char *, int, long *)); -int readdir_r __P((DIR *, struct dirent *, struct dirent **)); +DIR *__opendir2(const char *, int); +long telldir(DIR *); +void seekdir(DIR *, long); +int scandir(const char *, struct dirent ***, + int (*)(struct dirent *), int (*)(const void *, const void *)); +int alphasort(const void *, const void *); +int getdirentries(int, char *, int, long *); +int readdir_r(DIR *, struct dirent *, struct dirent **); #endif /* not POSIX */ __END_DECLS diff --git a/include/err.h b/include/err.h index 7af694b..9195051 100644 --- a/include/err.h +++ b/include/err.h @@ -71,14 +71,21 @@ #include __BEGIN_DECLS -__dead void err __P((int, const char *, ...)) __attribute__((__noreturn__)); -__dead void verr __P((int, const char *, _BSD_VA_LIST_)) __attribute__((__noreturn__)); -__dead void errx __P((int, const char *, ...)) __attribute__((__noreturn__)); -__dead void verrx __P((int, const char *, _BSD_VA_LIST_)) __attribute__((__noreturn__)); -void warn __P((const char *, ...)); -void vwarn __P((const char *, _BSD_VA_LIST_)); -void warnx __P((const char *, ...)); -void vwarnx __P((const char *, _BSD_VA_LIST_)); +void err(int, const char *, ...) __dead2; +void verr(int, const char *, _BSD_VA_LIST_) __dead2; +void errc(int, int, const char *, ...) __dead2; +void verrc(int, int, const char *, _BSD_VA_LIST_) __dead2; +void errx(int, const char *, ...) __dead2; +void verrx(int, const char *, _BSD_VA_LIST_) __dead2; +void warn(const char *, ...); +void vwarn(const char *, _BSD_VA_LIST_); +void warnc(int, const char *, ...); +void vwarnc(int, const char *, _BSD_VA_LIST_); +void warnx(const char *, ...); +void vwarnx(const char *, _BSD_VA_LIST_); +void err_set_file(void *); +void err_set_exit(void (*)(int)); + __END_DECLS #endif /* !_ERR_H_ */ diff --git a/include/fnmatch.h b/include/fnmatch.h index b321ce4..945c94f 100644 --- a/include/fnmatch.h +++ b/include/fnmatch.h @@ -77,7 +77,7 @@ __BEGIN_DECLS #ifndef _POSIX_SOURCE -int fnmatch __P((const char *, const char *, int)); +int fnmatch(const char *, const char *, int); #endif __END_DECLS diff --git a/include/fstab.h b/include/fstab.h index 3f3cb93..fdd484a 100644 --- a/include/fstab.h +++ b/include/fstab.h @@ -93,11 +93,11 @@ struct fstab { #include __BEGIN_DECLS -struct fstab *getfsent __P((void)); -struct fstab *getfsspec __P((const char *)); -struct fstab *getfsfile __P((const char *)); -int setfsent __P((void)); -void endfsent __P((void)); +struct fstab *getfsent(void); +struct fstab *getfsspec(const char *); +struct fstab *getfsfile(const char *); +int setfsent(void); +void endfsent(void); __END_DECLS #endif /* !_FSTAB_H_ */ diff --git a/include/fts.h b/include/fts.h index 410368f..4977b77 100644 --- a/include/fts.h +++ b/include/fts.h @@ -141,12 +141,12 @@ typedef struct _ftsent { #include __BEGIN_DECLS -FTSENT *fts_children __P((FTS *, int)); -int fts_close __P((FTS *)); -FTS *fts_open __P((char * const *, int, - int (*)(const FTSENT **, const FTSENT **))); -FTSENT *fts_read __P((FTS *)); -int fts_set __P((FTS *, FTSENT *, int)); +FTSENT *fts_children(FTS *, int); +int fts_close(FTS *); +FTS *fts_open(char * const *, int, + int (*)(const FTSENT **, const FTSENT **)); +FTSENT *fts_read(FTS *); +int fts_set(FTS *, FTSENT *, int); __END_DECLS #endif /* !_FTS_H_ */ diff --git a/include/getopt.h b/include/getopt.h new file mode 100644 index 0000000..270fed8 --- /dev/null +++ b/include/getopt.h @@ -0,0 +1,72 @@ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ + +/*- + * 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. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#include +#include + +/* + * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions + */ +#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +__BEGIN_DECLS +int getopt_long(int, char * const *, const char *, const struct option *, int *); +__END_DECLS +#endif + +#endif /* !_GETOPT_H_ */ diff --git a/include/glob.h b/include/glob.h index f9c1875..ef67b20 100644 --- a/include/glob.h +++ b/include/glob.h @@ -73,18 +73,18 @@ typedef struct { int gl_flags; /* Copy of flags parameter to glob. */ char **gl_pathv; /* List of paths matching pattern. */ /* Copy of errfunc parameter to glob. */ - int (*gl_errfunc) __P((const char *, int)); + int (*gl_errfunc)(const char *, int); /* * Alternate filesystem access methods for glob; replacement * versions of closedir(3), readdir(3), opendir(3), stat(2) * and lstat(2). */ - void (*gl_closedir) __P((void *)); - struct dirent *(*gl_readdir) __P((void *)); - void *(*gl_opendir) __P((const char *)); - int (*gl_lstat) __P((const char *, struct stat *)); - int (*gl_stat) __P((const char *, struct stat *)); + void (*gl_closedir)(void *); + struct dirent *(*gl_readdir)(void *); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, struct stat *); + int (*gl_stat)(const char *, struct stat *); } glob_t; #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ @@ -107,8 +107,8 @@ typedef struct { #define GLOB_ABEND (-2) /* Unignored error. */ __BEGIN_DECLS -int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); -void globfree __P((glob_t *)); +int glob(const char *, int, int (*)(const char *, int), glob_t *); +void globfree(glob_t *); __END_DECLS #endif /* !_GLOB_H_ */ diff --git a/include/grp.h b/include/grp.h index abbc34e..6d8d293 100644 --- a/include/grp.h +++ b/include/grp.h @@ -79,16 +79,19 @@ struct group { #include __BEGIN_DECLS -struct group *getgrgid __P((gid_t)); -struct group *getgrnam __P((const char *)); -int getgrgid_r __P((gid_t, struct group *, char *, size_t, struct group **)); -int getgrnam_r __P((const char *, struct group *, char *, size_t, struct group **)); +struct group *getgrgid(gid_t); +struct group *getgrnam(const char *); +int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **); +int getgrnam_r(const char *, struct group *, char *, size_t, struct group **); #ifndef _POSIX_SOURCE -struct group *getgrent __P((void)); -int setgrent __P((void)); -void endgrent __P((void)); -void setgrfile __P((const char *)); -int setgroupent __P((int)); +struct group *getgrent(void); +#ifndef _XOPEN_SOURCE +char *group_from_gid(gid_t, int); +#endif +int setgrent(void); +void endgrent(void); +void setgrfile(const char *); +int setgroupent(int); #endif __END_DECLS diff --git a/include/iso646.h b/include/iso646.h new file mode 100644 index 0000000..392b19f --- /dev/null +++ b/include/iso646.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 1998 Alex Nash + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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/include/iso646.h,v 1.4 2002/09/18 22:23:59 mike Exp $ + */ + +#ifndef _ISO646_H_ +#define _ISO646_H_ + +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= + +#endif /* !_ISO646_H_ */ diff --git a/include/kvm.h b/include/kvm.h index 4575ffb..f71f40e 100644 --- a/include/kvm.h +++ b/include/kvm.h @@ -72,21 +72,21 @@ __BEGIN_DECLS typedef struct __kvm kvm_t; struct kinfo_proc; -int kvm_close __P((kvm_t *)); -char **kvm_getargv __P((kvm_t *, const struct kinfo_proc *, int)); -char **kvm_getenvv __P((kvm_t *, const struct kinfo_proc *, int)); -char *kvm_geterr __P((kvm_t *)); -int kvm_getloadavg __P((kvm_t *, double [], int)); -char *kvm_getfiles __P((kvm_t *, int, int, int *)); +int kvm_close(kvm_t *); +char **kvm_getargv(kvm_t *, const struct kinfo_proc *, int); +char **kvm_getenvv(kvm_t *, const struct kinfo_proc *, int); +char *kvm_geterr(kvm_t *); +int kvm_getloadavg(kvm_t *, double [], int); +char *kvm_getfiles(kvm_t *, int, int, int *); struct kinfo_proc * - kvm_getprocs __P((kvm_t *, int, int, int *)); -int kvm_nlist __P((kvm_t *, struct nlist *)); + kvm_getprocs(kvm_t *, int, int, int *); +int kvm_nlist(kvm_t *, struct nlist *); kvm_t *kvm_open - __P((const char *, const char *, const char *, int, const char *)); + (const char *, const char *, const char *, int, const char *); kvm_t *kvm_openfiles - __P((const char *, const char *, const char *, int, char *)); -int kvm_read __P((kvm_t *, unsigned long, void *, unsigned int)); -int kvm_write __P((kvm_t *, unsigned long, const void *, unsigned int)); + (const char *, const char *, const char *, int, char *); +int kvm_read(kvm_t *, unsigned long, void *, unsigned int); +int kvm_write(kvm_t *, unsigned long, const void *, unsigned int); __END_DECLS diff --git a/include/langinfo.h b/include/langinfo.h new file mode 100644 index 0000000..ab26dd3 --- /dev/null +++ b/include/langinfo.h @@ -0,0 +1,121 @@ +/*- + * 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. + * + * $FreeBSD: /repoman/r/ncvs/src/include/langinfo.h,v 1.6 2002/09/18 05:54:25 mike Exp $ + */ + +#ifndef _LANGINFO_H_ +#define _LANGINFO_H_ + +#include +#include + +#ifndef _NL_ITEM_DECLARED +typedef int nl_item; +#define _NL_ITEM_DECLARED +#endif + +#define CODESET 0 /* codeset name */ +#define D_T_FMT 1 /* string for formatting date and time */ +#define D_FMT 2 /* date format string */ +#define T_FMT 3 /* time format string */ +#define T_FMT_AMPM 4 /* a.m. or p.m. time formatting string */ +#define AM_STR 5 /* Ante Meridian affix */ +#define PM_STR 6 /* Post Meridian affix */ + +/* week day names */ +#define DAY_1 7 +#define DAY_2 8 +#define DAY_3 9 +#define DAY_4 10 +#define DAY_5 11 +#define DAY_6 12 +#define DAY_7 13 + +/* abbreviated week day names */ +#define ABDAY_1 14 +#define ABDAY_2 15 +#define ABDAY_3 16 +#define ABDAY_4 17 +#define ABDAY_5 18 +#define ABDAY_6 19 +#define ABDAY_7 20 + +/* month names */ +#define MON_1 21 +#define MON_2 22 +#define MON_3 23 +#define MON_4 24 +#define MON_5 25 +#define MON_6 26 +#define MON_7 27 +#define MON_8 28 +#define MON_9 29 +#define MON_10 30 +#define MON_11 31 +#define MON_12 32 + +/* abbreviated month names */ +#define ABMON_1 33 +#define ABMON_2 34 +#define ABMON_3 35 +#define ABMON_4 36 +#define ABMON_5 37 +#define ABMON_6 38 +#define ABMON_7 39 +#define ABMON_8 40 +#define ABMON_9 41 +#define ABMON_10 42 +#define ABMON_11 43 +#define ABMON_12 44 + +#define ERA 45 /* era description segments */ +#define ERA_D_FMT 46 /* era date format string */ +#define ERA_D_T_FMT 47 /* era date and time format string */ +#define ERA_T_FMT 48 /* era time format string */ +#define ALT_DIGITS 49 /* alternative symbols for digits */ + +#define RADIXCHAR 50 /* radix char */ +#define THOUSEP 51 /* separator for thousands */ + +#define YESEXPR 52 /* affirmative response expression */ +#define NOEXPR 53 /* negative response expression */ + +#if !defined(_ANSI_SOURCE) +#define YESSTR 54 /* affirmative response for yes/no queries */ +#define NOSTR 55 /* negative response for yes/no queries */ +#endif + +#define CRNCYSTR 56 /* currency symbol */ + +#if !defined(_ANSI_SOURCE) +#define D_MD_ORDER 57 /* month/day order (local extension) */ +#endif + +__BEGIN_DECLS +char *nl_langinfo(nl_item); +__END_DECLS + +#endif /* !_LANGINFO_H_ */ diff --git a/include/libc.h b/include/libc.h index 42c5f0c..149d267 100644 --- a/include/libc.h +++ b/include/libc.h @@ -26,8 +26,8 @@ * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ -#ifndef LIBC_H -#define LIBC_H +#ifndef _LIBC_H +#define _LIBC_H #include #include @@ -68,8 +68,11 @@ struct qelem { char *q_data; }; +#include + +__BEGIN_DECLS extern kern_return_t map_fd(int fd, vm_offset_t offset, vm_offset_t *addr, boolean_t find_space, vm_size_t numbytes); - +__END_DECLS #endif /* _LIBC_H */ diff --git a/include/libgen.h b/include/libgen.h index a679433..e097870 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -35,11 +35,11 @@ __BEGIN_DECLS -char *basename __P((const char *)); -char *dirname __P((const char *)); +char *basename(const char *); +char *dirname(const char *); #if 0 -char *regcmp __P((const char *, ...)); -char *regex __P((const char *, const char *, ...)); +char *regcmp(const char *, ...); +char *regex(const char *, const char *, ...); extern char *__loc1; #endif diff --git a/include/locale.h b/include/locale.h index 0c1a6bc..40ad943 100644 --- a/include/locale.h +++ b/include/locale.h @@ -31,6 +31,7 @@ * SUCH DAMAGE. * * @(#)locale.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: /repoman/r/ncvs/src/include/locale.h,v 1.7 2002/10/09 09:19:27 tjr Exp $ */ #ifndef _LOCALE_H_ @@ -55,6 +56,12 @@ struct lconv { 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; }; #ifndef NULL @@ -74,8 +81,8 @@ struct lconv { #include __BEGIN_DECLS -struct lconv *localeconv __P((void)); -char *setlocale __P((int, const char *)); +struct lconv *localeconv(void); +char *setlocale(int, const char *); __END_DECLS #endif /* _LOCALE_H_ */ diff --git a/include/malloc/Makefile.inc b/include/malloc/Makefile.inc new file mode 100644 index 0000000..47a51ee --- /dev/null +++ b/include/malloc/Makefile.inc @@ -0,0 +1,2 @@ +MALLOC_INSTHDRS += malloc.h +MALLOC_INSTHDRS := ${MALLOC_INSTHDRS:S/^/${.CURDIR}\/include\/malloc\//} diff --git a/include/malloc/malloc.h b/include/malloc/malloc.h new file mode 100644 index 0000000..c6a4172 --- /dev/null +++ b/include/malloc/malloc.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 _MALLOC_MALLOC_H_ +#define _MALLOC_MALLOC_H_ + +#include +#include +#include + +__BEGIN_DECLS +/********* Type definitions ************/ + +typedef struct _malloc_zone_t { + /* Only zone implementors should depend on the layout of this structure; + Regular callers should use the access functions below */ + unsigned version; + void *reserved2; + size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */ + void *(*malloc)(struct _malloc_zone_t *zone, size_t size); + void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */ + void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */ + void (*free)(struct _malloc_zone_t *zone, void *ptr); + void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size); + void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */ + const char *zone_name; + + /* Optional batch callbacks; these may be NULL */ + unsigned (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */ + void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */ + + struct malloc_introspection_t *introspect; + void *reserved5; +} malloc_zone_t; + +/********* Creation and destruction ************/ + +extern malloc_zone_t *malloc_default_zone(void); + /* The initial zone */ + +extern malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags); + /* Create a new zone */ + +extern void malloc_destroy_zone(malloc_zone_t *zone); + /* Destroys zone and everything it allocated */ + +/********* Block creation and manipulation ************/ + +extern void *malloc_zone_malloc(malloc_zone_t *zone, size_t size); + /* Allocates a new pointer of size size; zone must be non-NULL */ + +extern void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size); + /* Allocates a new pointer of size num_items * size; block is cleared; zone must be non-NULL */ + +extern void *malloc_zone_valloc(malloc_zone_t *zone, size_t size); + /* Allocates a new pointer of size size; zone must be non-NULL; Pointer is guaranteed to be page-aligned and block is cleared */ + +extern void malloc_zone_free(malloc_zone_t *zone, void *ptr); + /* Frees pointer in zone; zone must be non-NULL */ + +extern void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size); + /* Enlarges block if necessary; zone must be non-NULL */ + +extern malloc_zone_t *malloc_zone_from_ptr(const void *ptr); + /* Returns the zone for a pointer, or NULL if not in any zone. + The ptr must have been returned from a malloc or realloc call. */ + +extern size_t malloc_size(const void *ptr); + /* Returns size of given ptr */ + +/********* Batch methods ************/ + +extern unsigned malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); + /* Allocates num blocks of the same size; Returns the number truly allocated (may be 0) */ + +extern void malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num); + /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process; This function will always free even if the zone has no batch callback */ + +/********* Functions for zone implementors ************/ + +extern void malloc_zone_register(malloc_zone_t *zone); + /* Registers a freshly created zone; + Should typically be called after a zone has been created */ + +extern void malloc_zone_unregister(malloc_zone_t *zone); + /* De-registers a zone + Should typically be called before calling the zone destruction routine */ + +extern void malloc_set_zone_name(malloc_zone_t *zone, const char *name); + /* Sets the name of a zone */ + +extern const char *malloc_get_zone_name(malloc_zone_t *zone); + /* Returns the name of a zone */ + +typedef struct { + vm_address_t address; + vm_size_t size; +} vm_range_t; + +typedef struct malloc_statistics_t { + unsigned blocks_in_use; + size_t size_in_use; + size_t max_size_in_use; /* high water mark of touched memory */ + size_t size_allocated; /* reserved in memory */ +} malloc_statistics_t; + +typedef kern_return_t memory_reader_t(task_t remote_task, vm_address_t remote_address, vm_size_t size, void **local_memory); + /* given a task, "reads" the memory at the given address and size +local_memory: set to a contiguous chunk of memory; validity of local_memory is assumed to be limited (until next call) */ + +#define MALLOC_PTR_IN_USE_RANGE_TYPE 1 /* for allocated pointers */ +#define MALLOC_PTR_REGION_RANGE_TYPE 2 /* for region containing pointers */ +#define MALLOC_ADMIN_REGION_RANGE_TYPE 4 /* for region used internally */ + +typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned); + /* given a task and context, "records" the specified addresses */ + +typedef struct malloc_introspection_t { + kern_return_t (*enumerator)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */ + size_t (*good_size)(malloc_zone_t *zone, size_t size); + boolean_t (*check)(malloc_zone_t *zone); /* Consistency checker */ + void (*print)(malloc_zone_t *zone, boolean_t verbose); /* Prints zone */ + void (*log)(malloc_zone_t *zone, void *address); /* Enables logging of activity */ + void (*force_lock)(malloc_zone_t *zone); /* Forces locking zone */ + void (*force_unlock)(malloc_zone_t *zone); /* Forces unlocking zone */ + void (*statistics)(malloc_zone_t *zone, malloc_statistics_t *stats); /* Fills statistics */ +} malloc_introspection_t; + +extern void malloc_printf(const char *format, ...); + /* Convenience for logging errors and warnings; + No allocation is performed during execution of this function; + Only understands usual %p %d %s formats, and %y that expresses a number of bytes (5b,10KB,1MB...) + */ + +/********* Functions for performance tools ************/ + +extern kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count); + /* Fills addresses and count with the addresses of the zones in task; + Note that the validity of the addresses returned correspond to the validity of the memory returned by reader */ + +/********* Debug helpers ************/ + +extern void malloc_zone_print_ptr_info(void *ptr); + /* print to stdout if this pointer is in the malloc heap, free status, and size */ + +extern boolean_t malloc_zone_check(malloc_zone_t *zone); + /* Checks zone is well formed; if !zone, checks all zones */ + +extern void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose); + /* Prints summary on zone; if !zone, prints all zones */ + +extern void malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats); + /* Fills statistics for zone; if !zone, sums up all zones */ + +extern void malloc_zone_log(malloc_zone_t *zone, void *address); + /* Controls logging of all activity; if !zone, for all zones; + If address==0 nothing is logged; + If address==-1 all activity is logged; + Else only the activity regarding address is logged */ +__END_DECLS + +#endif /* _MALLOC_MALLOC_H_ */ diff --git a/include/monetary.h b/include/monetary.h new file mode 100644 index 0000000..5567519 --- /dev/null +++ b/include/monetary.h @@ -0,0 +1,39 @@ +/*- + * 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. + * + * $FreeBSD: /repoman/r/ncvs/src/include/monetary.h,v 1.7 2002/09/20 08:22:48 mike Exp $ + */ + +#ifndef _MONETARY_H_ +#define _MONETARY_H_ + +#include +#include + +__BEGIN_DECLS +ssize_t strfmon(char *, size_t, const char *, ...); +__END_DECLS + +#endif /* !_MONETARY_H_ */ diff --git a/include/monitor.h b/include/monitor.h index 8c5b0e8..db99210 100644 --- a/include/monitor.h +++ b/include/monitor.h @@ -32,6 +32,9 @@ #ifndef __MONITOR_HEADER__ #define __MONITOR_HEADER__ +#include + +__BEGIN_DECLS extern void monstartup (char *lowpc, char *highpc); extern void monitor (char *lowpc, char *highpc, char *buf, int bufsiz, int cntsiz); @@ -43,5 +46,6 @@ extern void monoutput (const char *filename); extern void moninit (void); extern void monreset (void); +__END_DECLS #endif /* __MONITOR_HEADER__ */ diff --git a/include/mpool.h b/include/mpool.h index 855bd2f..e811aa3 100644 --- a/include/mpool.h +++ b/include/mpool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,7 @@ * @APPLE_LICENSE_HEADER_END@ */ /*- - * Copyright (c) 1991, 1993 + * 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 @@ -54,106 +54,76 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)mpool.h 8.1 (Berkeley) 6/2/93 + * @(#)mpool.h 8.2 (Berkeley) 7/14/94 + * $FreeBSD: src/include/mpool.h,v 1.9 2002/03/23 17:24:53 imp Exp $ */ +#ifndef _MPOOL_H_ +#define _MPOOL_H_ + +#include + /* - * The memory pool scheme is a simple one. Each in memory page is referenced - * by a bucket which is threaded in three ways. All active pages are threaded - * on a hash chain (hashed by the page number) and an lru chain. Inactive - * pages are threaded on a free chain. Each reference to a memory pool is - * handed an MPOOL which is the opaque cookie passed to all of the memory - * routines. + * The memory pool scheme is a simple one. Each in-memory page is referenced + * by a bucket which is threaded in up to two of three ways. All active pages + * are threaded on a hash chain (hashed by page number) and an lru chain. + * Inactive pages are threaded on a free chain. Each reference to a memory + * pool is handed an opaque MPOOL cookie which stores all of this information. */ #define HASHSIZE 128 #define HASHKEY(pgno) ((pgno - 1) % HASHSIZE) -/* The BKT structures are the elements of the lists. */ -typedef struct BKT { - struct BKT *hnext; /* next hash bucket */ - struct BKT *hprev; /* previous hash bucket */ - struct BKT *cnext; /* next free/lru bucket */ - struct BKT *cprev; /* previous free/lru bucket */ - void *page; /* page */ - pgno_t pgno; /* page number */ +/* The BKT structures are the elements of the queues. */ +typedef struct _bkt { + TAILQ_ENTRY(_bkt) hq; /* hash queue */ + TAILQ_ENTRY(_bkt) q; /* lru queue */ + void *page; /* page */ + pgno_t pgno; /* page number */ #define MPOOL_DIRTY 0x01 /* page needs to be written */ #define MPOOL_PINNED 0x02 /* page is pinned into memory */ - unsigned long flags; /* flags */ + u_int8_t flags; /* flags */ } BKT; -/* The BKTHDR structures are the heads of the lists. */ -typedef struct BKTHDR { - struct BKT *hnext; /* next hash bucket */ - struct BKT *hprev; /* previous hash bucket */ - struct BKT *cnext; /* next free/lru bucket */ - struct BKT *cprev; /* previous free/lru bucket */ -} BKTHDR; - typedef struct MPOOL { - BKTHDR free; /* The free list. */ - BKTHDR lru; /* The LRU list. */ - BKTHDR hashtable[HASHSIZE]; /* Hashed list by page number. */ - pgno_t curcache; /* Current number of cached pages. */ - pgno_t maxcache; /* Max number of cached pages. */ - pgno_t npages; /* Number of pages in the file. */ - u_long pagesize; /* File page size. */ - int fd; /* File descriptor. */ - /* Page in conversion routine. */ - void (*pgin) __P((void *, pgno_t, void *)); - /* Page out conversion routine. */ - void (*pgout) __P((void *, pgno_t, void *)); - void *pgcookie; /* Cookie for page in/out routines. */ + TAILQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */ + /* hash queue array */ + TAILQ_HEAD(_hqh, _bkt) hqh[HASHSIZE]; + pgno_t curcache; /* current number of cached pages */ + pgno_t maxcache; /* max number of cached pages */ + pgno_t npages; /* number of pages in the file */ + u_long pagesize; /* file page size */ + int fd; /* file descriptor */ + /* page in conversion routine */ + void (*pgin)(void *, pgno_t, void *); + /* page out conversion routine */ + void (*pgout)(void *, pgno_t, void *); + void *pgcookie; /* cookie for page in/out routines */ #ifdef STATISTICS - unsigned long cachehit; - unsigned long cachemiss; - unsigned long pagealloc; - unsigned long pageflush; - unsigned long pageget; - unsigned long pagenew; - unsigned long pageput; - unsigned long pageread; - unsigned long pagewrite; + u_long cachehit; + u_long cachemiss; + u_long pagealloc; + u_long pageflush; + u_long pageget; + u_long pagenew; + u_long pageput; + u_long pageread; + u_long pagewrite; #endif } MPOOL; -#ifdef __MPOOLINTERFACE_PRIVATE -/* Macros to insert/delete into/from hash chain. */ -#define rmhash(bp) { \ - (bp)->hprev->hnext = (bp)->hnext; \ - (bp)->hnext->hprev = (bp)->hprev; \ -} -#define inshash(bp, pg) { \ - hp = &mp->hashtable[HASHKEY(pg)]; \ - (bp)->hnext = hp->hnext; \ - (bp)->hprev = (struct BKT *)hp; \ - hp->hnext->hprev = (bp); \ - hp->hnext = (bp); \ -} - -/* Macros to insert/delete into/from lru and free chains. */ -#define rmchain(bp) { \ - (bp)->cprev->cnext = (bp)->cnext; \ - (bp)->cnext->cprev = (bp)->cprev; \ -} -#define inschain(bp, dp) { \ - (bp)->cnext = (dp)->cnext; \ - (bp)->cprev = (struct BKT *)(dp); \ - (dp)->cnext->cprev = (bp); \ - (dp)->cnext = (bp); \ -} -#endif - __BEGIN_DECLS -MPOOL *mpool_open __P((DBT *, int, pgno_t, pgno_t)); -void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *), - void (*)(void *, pgno_t, void *), void *)); -void *mpool_new __P((MPOOL *, pgno_t *)); -void *mpool_get __P((MPOOL *, pgno_t, u_int)); -int mpool_put __P((MPOOL *, void *, u_int)); -int mpool_sync __P((MPOOL *)); -int mpool_close __P((MPOOL *)); +MPOOL *mpool_open(void *, int, pgno_t, pgno_t); +void mpool_filter(MPOOL *, void (*)(void *, pgno_t, void *), + void (*)(void *, pgno_t, void *), void *); +void *mpool_new(MPOOL *, pgno_t *); +void *mpool_get(MPOOL *, pgno_t, u_int); +int mpool_put(MPOOL *, void *, u_int); +int mpool_sync(MPOOL *); +int mpool_close(MPOOL *); #ifdef STATISTICS -void mpool_stat __P((MPOOL *)); +void mpool_stat(MPOOL *); #endif __END_DECLS + +#endif diff --git a/include/ndbm.h b/include/ndbm.h index d68c882..5392266 100644 --- a/include/ndbm.h +++ b/include/ndbm.h @@ -87,15 +87,17 @@ typedef DB DBM; #define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE __BEGIN_DECLS -void dbm_close __P((DBM *)); -int dbm_delete __P((DBM *, datum)); -datum dbm_fetch __P((DBM *, datum)); -datum dbm_firstkey __P((DBM *)); -long dbm_forder __P((DBM *, datum)); -datum dbm_nextkey __P((DBM *)); -DBM *dbm_open __P((const char *, int, int)); -int dbm_store __P((DBM *, datum, datum, int)); -int dbm_dirfno __P((DBM *)); +void dbm_close(DBM *); +int dbm_clearerr( DBM *); +int dbm_delete(DBM *, datum); +int dbm_error( DBM *); +datum dbm_fetch(DBM *, datum); +datum dbm_firstkey(DBM *); +long dbm_forder(DBM *, datum); +datum dbm_nextkey(DBM *); +DBM *dbm_open(const char *, int, int); +int dbm_store(DBM *, datum, datum, int); +int dbm_dirfno(DBM *); __END_DECLS #endif /* !_NDBM_H_ */ diff --git a/include/netdb.h b/include/netdb.h deleted file mode 100644 index f43a1b2..0000000 --- a/include/netdb.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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++ 1980, 1983, 1988, 1993 - * - - * Copyright (c) 1980, 1983, 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. - * - - * 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-- - */ - -/* - * @(#)netdb.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _NETDB_H_ -#define _NETDB_H_ - -#include -#include - -#define _PATH_HEQUIV "/etc/hosts.equiv" -#define _PATH_HOSTS "/etc/hosts" -#define _PATH_NETWORKS "/etc/networks" -#define _PATH_PROTOCOLS "/etc/protocols" -#define _PATH_SERVICES "/etc/services" - -extern int h_errno; - -/* - * Structures returned by network data base library. All addresses are - * supplied in host order, and returned in network order (suitable for - * use in system calls). - */ -struct hostent { - char *h_name; /* official name of host */ - char **h_aliases; /* alias list */ - int h_addrtype; /* host address type */ - int h_length; /* length of address */ - char **h_addr_list; /* list of addresses from name server */ -#define h_addr h_addr_list[0] /* address, for backward compatiblity */ -}; - -/* - * Assumption here is that a network number - * fits in an unsigned long -- probably a poor one. - */ -struct netent { - char *n_name; /* official name of net */ - char **n_aliases; /* alias list */ - int n_addrtype; /* net address type */ - unsigned long n_net; /* network # */ -}; - -struct servent { - char *s_name; /* official service name */ - char **s_aliases; /* alias list */ - int s_port; /* port # */ - char *s_proto; /* protocol to use */ -}; - -struct protoent { - char *p_name; /* official protocol name */ - char **p_aliases; /* alias list */ - int p_proto; /* protocol # */ -}; - -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; - -struct rpcent { - char *r_name; /* name of server for this rpc program */ - char **r_aliases; /* alias list */ - int r_number; /* rpc program number */ -}; - -/* - * Error return codes from gethostbyname() and gethostbyaddr() - * (left in extern int h_errno). - */ - -#define NETDB_INTERNAL -1 /* see errno */ -#define NETDB_SUCCESS 0 /* no problem */ -#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ -#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ -#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ -#define NO_DATA 4 /* Valid name, no data record of requested type */ -#define NO_ADDRESS NO_DATA /* no address, look for MX record */ - -/* - * Error return codes from getaddrinfo() - */ -#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ -#define EAI_FAMILY 5 /* ai_family not supported */ -#define EAI_MEMORY 6 /* memory allocation failure */ -#define EAI_NODATA 7 /* no address associated with hostname */ -#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ -#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#define EAI_SYSTEM 11 /* system error returned in errno */ -#define EAI_BADHINTS 12 -#define EAI_PROTOCOL 13 -#define EAI_MAX 14 - -/* - * Flag values for getaddrinfo() - */ -#define AI_PASSIVE 0x00000001 /* get address to use bind() */ -#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ -#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ -/* valid flags for addrinfo */ -#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) - -#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ -#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ -#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ -#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ -/* special recommended flags for getipnodebyname */ -#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) - -/* - * Constants for getnameinfo() - */ -#define NI_MAXHOST 1025 -#define NI_MAXSERV 32 - -/* - * Flag values for getnameinfo() - */ -#define NI_NOFQDN 0x00000001 -#define NI_NUMERICHOST 0x00000002 -#define NI_NAMEREQD 0x00000004 -#define NI_NUMERICSERV 0x00000008 -#define NI_DGRAM 0x00000010 -#define NI_WITHSCOPEID 0x00000020 - -/* - * Scope delimit character - */ -#define SCOPE_DELIMITER '%' - -__BEGIN_DECLS -void endhostent __P((void)); -void endnetent __P((void)); -void endprotoent __P((void)); -void endservent __P((void)); -void freehostent __P((struct hostent *)); -struct hostent *gethostbyaddr __P((const char *, int, int)); -struct hostent *gethostbyname __P((const char *)); -struct hostent *gethostbyname2 __P((const char *, int)); -struct hostent *gethostent __P((void)); -struct hostent *getipnodebyaddr __P((const void *, size_t, int, int *)); -struct hostent *getipnodebyname __P((const char *, int, int, int *)); -struct netent *getnetbyaddr __P((long, int)); -struct netent *getnetbyname __P((const char *)); -struct netent *getnetent __P((void)); -struct protoent *getprotobyname __P((const char *)); -struct protoent *getprotobynumber __P((int)); -struct protoent *getprotoent __P((void)); -struct servent *getservbyname __P((const char *, const char *)); -struct servent *getservbyport __P((int, const char *)); -struct servent *getservent __P((void)); -struct rpcent *getrpcbyname __P((const char *name)); -struct rpcent *getrpcbynumber __P((long number)); -struct rpcent *getrpcent __P((void)); -void setrpcent __P((int stayopen)); -void endrpcent __P((void)); - -void herror __P((const char *)); -char *hstrerror __P((int)); -void sethostent __P((int)); -/* void sethostfile __P((const char *)); */ -void setnetent __P((int)); -void setprotoent __P((int)); -void setservent __P((int)); - -char *gai_strerror __P((int)); -void freeaddrinfo __P((struct addrinfo *)); -int getaddrinfo __P((const char *, const char *, const struct addrinfo *, struct addrinfo **)); -int getnameinfo __P((const struct sockaddr *, size_t, char *, size_t, char *, size_t, int)); -__END_DECLS - -#endif /* !_NETDB_H_ */ diff --git a/include/nl_types.h b/include/nl_types.h new file mode 100644 index 0000000..4814c1d --- /dev/null +++ b/include/nl_types.h @@ -0,0 +1,51 @@ +/* $FreeBSD: src/include/nl_types.h,v 1.7 1999/08/27 23:44:51 peter Exp $ */ + +/*********************************************************** +Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that Alfalfa's name not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +If you make any modifications, bugfixes or other changes to this software +we'd appreciate it if you could send a copy to us so we can keep things +up-to-date. Many thanks. + Kee Hinckley + Alfalfa Software, Inc. + 267 Allston St., #3 + Cambridge, MA 02139 USA + nazgul@alfalfa.com + +******************************************************************/ + +#ifndef _NL_TYPES_H_ +#define _NL_TYPES_H_ +#include + +#define NL_SETD 0 +#define NL_CAT_LOCALE 1 + +typedef int nl_item; +typedef void *nl_catd; + +__BEGIN_DECLS +extern nl_catd catopen(__const char *, int); +extern char *catgets(nl_catd, int, int, __const char *); +extern int catclose(nl_catd); +__END_DECLS + +#endif /* _NL_TYPES_H_ */ diff --git a/include/nlist.h b/include/nlist.h index 426e2d4..835aa79 100644 --- a/include/nlist.h +++ b/include/nlist.h @@ -103,7 +103,7 @@ struct nlist { #include __BEGIN_DECLS -int nlist __P((const char *, struct nlist *)); +int nlist(const char *, struct nlist *); __END_DECLS #endif /* !_NLIST_H_ */ diff --git a/include/objc/malloc.h b/include/objc/malloc.h index ef08a95..ae45bbd 100644 --- a/include/objc/malloc.h +++ b/include/objc/malloc.h @@ -23,132 +23,5 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import -#import - -/********* Type definitions ************/ - -typedef struct _malloc_zone_t { - /* Only zone implementors should depend on the layout of this structure; - Regular callers should use the access functions below */ - void *reserved1; - void *reserved2; - size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */ - void *(*malloc)(struct _malloc_zone_t *zone, size_t size); - void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */ - void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */ - void (*free)(struct _malloc_zone_t *zone, void *ptr); - void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size); - void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */ - const char *zone_name; - void *reserved3; - void *reserved4; - struct malloc_introspection_t *introspect; - void *reserved5; -} malloc_zone_t; - -/********* Creation and destruction ************/ - -extern malloc_zone_t *malloc_default_zone(void); - /* The initial zone */ - -extern malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags); - /* Create a new zone */ - -extern void malloc_destroy_zone(malloc_zone_t *zone); - /* Destroys zone and everything it allocated */ - -/********* Block creation and manipulation ************/ - -extern void *malloc_zone_malloc(malloc_zone_t *zone, size_t size); - /* Allocates a new pointer of size size; zone must be non-NULL */ - -extern void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size); - /* Allocates a new pointer of size num_items * size; block is cleared; zone must be non-NULL */ - -extern void *malloc_zone_valloc(malloc_zone_t *zone, size_t size); - /* Allocates a new pointer of size size; zone must be non-NULL; Pointer is guaranteed to be page-aligned and block is cleared */ - -extern void malloc_zone_free(malloc_zone_t *zone, void *ptr); - /* Frees pointer in zone; zone must be non-NULL */ - -extern void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size); - /* Enlarges block if necessary; zone must be non-NULL */ - -extern malloc_zone_t *malloc_zone_from_ptr(const void *ptr); - /* Returns the zone for a pointer, or NULL if not in any zone. - The ptr must have been returned from a malloc or realloc call. */ - -extern size_t malloc_size(const void *ptr); - /* Returns size of given ptr */ - -/********* Functions for zone implementors ************/ - -extern void malloc_zone_register(malloc_zone_t *zone); - /* Registers a freshly created zone; - Should typically be called after a zone has been created */ - -extern void malloc_zone_unregister(malloc_zone_t *zone); - /* De-registers a zone - Should typically be called before calling the zone destruction routine */ - -extern void malloc_set_zone_name(malloc_zone_t *zone, const char *name); - /* Sets the name of a zone */ - -extern const char *malloc_get_zone_name(malloc_zone_t *zone); - /* Returns the name of a zone */ - -typedef struct { - vm_address_t address; - vm_size_t size; -} vm_range_t; - -typedef kern_return_t memory_reader_t(task_t remote_task, vm_address_t remote_address, vm_size_t size, void **local_memory); - /* given a task, "reads" the memory at the given address and size -local_memory: set to a contiguous chunk of memory; validity of local_memory is assumed to be limited (until next call) */ - -#define MALLOC_PTR_IN_USE_RANGE_TYPE 1 /* for allocated pointers */ -#define MALLOC_PTR_REGION_RANGE_TYPE 2 /* for region containing pointers */ -#define MALLOC_ADMIN_REGION_RANGE_TYPE 4 /* for region used internally */ - -typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned); - /* given a task and context, "records" the specified addresses */ - -typedef struct malloc_introspection_t { - kern_return_t (*enumerator)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */ - size_t (*good_size)(malloc_zone_t *zone, size_t size); - boolean_t (*check)(malloc_zone_t *zone); /* Consistency checker */ - void (*print)(malloc_zone_t *zone, boolean_t verbose); /* Prints zone */ - void (*log)(malloc_zone_t *zone, void *address); /* Enables logging of activity */ - void (*force_lock)(malloc_zone_t *zone); /* Forces locking zone */ - void (*force_unlock)(malloc_zone_t *zone); /* Forces unlocking zone */ -} malloc_introspection_t; - -extern void malloc_printf(const char *format, ...); - /* Convenience for logging errors and warnings; - No allocation is performed during execution of this function; - Only understand %p %d %x %s formats - */ - -/********* Functions for performance tools ************/ - -extern kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count); - /* Fills addresses and count with the addresses of the zones in task; - Note that the validity of the addresses returned correspond to the validity of the memory returned by reader */ - -/********* Debug helpers ************/ - -extern void malloc_zone_print_ptr_info(void *ptr); - /* print to stdout if this pointer is in the malloc heap, free status, and size */ - -extern boolean_t malloc_zone_check(malloc_zone_t *zone); - /* Checks zone is well formed; if !zone, checks all zones */ - -extern void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose); - /* Prints summary on zone; if !zone, prints all zones */ - -extern void malloc_zone_log(malloc_zone_t *zone, void *address); - /* Controls logging of all activity; if !zone, for all zones; - If address==0 nothing is logged; - If address==-1 all activity is logged; - Else only the activity regarding address is logged */ +#warning "Use instead of " +#include diff --git a/include/objc/zone.h b/include/objc/zone.h index f91bd39..dad1012 100644 --- a/include/objc/zone.h +++ b/include/objc/zone.h @@ -23,7 +23,10 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import +#ifndef _OBJC_ZONE_H_ +#define _OBJC_ZONE_H_ + +#import typedef malloc_zone_t NXZone; @@ -31,6 +34,9 @@ typedef malloc_zone_t NXZone; /********* Interface to zone based malloc ************/ +#include + +__BEGIN_DECLS extern NXZone *NXDefaultMallocZone(void); // Returns the default zone used by the malloc(3) calls @@ -55,4 +61,6 @@ extern void NXDestroyZone(malloc_zone_t *zone); extern NXZone *NXZoneFromPtr(void *ptr); // 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 +#endif /* _OBJC_ZONE_H_ */ diff --git a/include/pwd.h b/include/pwd.h index 2b9981c..68d1e0c 100644 --- a/include/pwd.h +++ b/include/pwd.h @@ -114,17 +114,18 @@ struct passwd { #include __BEGIN_DECLS -struct passwd *getpwuid __P((uid_t)); -struct passwd *getpwnam __P((const char *)); -int getpwuid_r __P((uid_t, struct passwd *, char *, size_t, struct passwd **)); -int getpwnam_r __P((const char *, struct passwd *, char *, size_t, struct passwd **)); +struct passwd *getpwuid(uid_t); +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 **); #ifndef _POSIX_SOURCE -struct passwd *getpwent __P((void)); +struct passwd *getpwent(void); #ifndef _XOPEN_SOURCE -int setpassent __P((int)); +int setpassent(int); +char *user_from_uid(uid_t, int); #endif -int setpwent __P((void)); -void endpwent __P((void)); +int setpwent(void); +void endpwent(void); #endif __END_DECLS diff --git a/include/readpassphrase.h b/include/readpassphrase.h new file mode 100644 index 0000000..8fbb8f5 --- /dev/null +++ b/include/readpassphrase.h @@ -0,0 +1,47 @@ +/* $OpenBSD: /usr/local/www/cvsroot/OpenBSD/src/include/readpassphrase.h,v 1.2 2002/02/16 21:27:17 millert Exp $ */ +/* $FreeBSD: /repoman/r/ncvs/src/include/readpassphrase.h,v 1.2 2002/03/08 20:52:52 green 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. + */ + +#ifndef _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ + +#include + +__BEGIN_DECLS +char * readpassphrase(const char *, char *, size_t, int); +__END_DECLS + +#endif /* !_READPASSPHRASE_H_ */ diff --git a/include/regex.h b/include/regex.h index 2f8f14e..2f078ef 100644 --- a/include/regex.h +++ b/include/regex.h @@ -120,11 +120,11 @@ typedef struct { #define REG_BACKR 02000 /* force use of backref code */ __BEGIN_DECLS -int regcomp __P((regex_t *, const char *, int)); -size_t regerror __P((int, const regex_t *, char *, size_t)); -int regexec __P((const regex_t *, - const char *, size_t, regmatch_t [], int)); -void regfree __P((regex_t *)); +int regcomp(regex_t *, const char *, int); +size_t regerror(int, const regex_t *, char *, size_t); +int regexec(const regex_t *, + const char *, size_t, regmatch_t [], int); +void regfree(regex_t *); __END_DECLS #endif /* !_REGEX_H_ */ diff --git a/include/regexp.h b/include/regexp.h index 3e90e4a..d086d62 100644 --- a/include/regexp.h +++ b/include/regexp.h @@ -84,10 +84,10 @@ typedef struct regexp { #include __BEGIN_DECLS -regexp *regcomp __P((const char *)); -int regexec __P((const regexp *, const char *)); -void regsub __P((const regexp *, const char *, char *)); -void regerror __P((const char *)); +regexp *regcomp(const char *); +int regexec(const regexp *, const char *); +void regsub(const regexp *, const char *, char *); +void regerror(const char *); __END_DECLS #endif /* !_REGEXP_H_ */ diff --git a/include/rune.h b/include/rune.h index c1e2b88..24f7c79 100644 --- a/include/rune.h +++ b/include/rune.h @@ -53,14 +53,14 @@ #define sputrune(c, s, n, r) (*__sputrune)((c), (s), (n), (r)) __BEGIN_DECLS -char *mbrune __P((const char *, rune_t)); -char *mbrrune __P((const char *, rune_t)); -char *mbmb __P((const char *, char *)); -long fgetrune __P((FILE *)); -int fputrune __P((rune_t, FILE *)); -int fungetrune __P((rune_t, FILE *)); -int setrunelocale __P((char *)); -void setinvalidrune __P((rune_t)); +char *mbrune(const char *, rune_t); +char *mbrrune(const char *, rune_t); +char *mbmb(const char *, char *); +long fgetrune(FILE *); +int fputrune(rune_t, FILE *); +int fungetrune(rune_t, FILE *); +int setrunelocale(char *); +void setinvalidrune(rune_t); __END_DECLS #endif /*! _RUNE_H_ */ diff --git a/include/runetype.h b/include/runetype.h index 84ce83f..2503670 100644 --- a/include/runetype.h +++ b/include/runetype.h @@ -42,19 +42,35 @@ #include #include -#ifndef _BSD_RUNE_T_DEFINED_ -#define _BSD_RUNE_T_DEFINED_ -typedef _BSD_RUNE_T_ rune_t; -#endif - #ifndef _BSD_SIZE_T_DEFINED_ #define _BSD_SIZE_T_DEFINED_ typedef _BSD_SIZE_T_ size_t; #endif +#ifndef _BSD_CT_RUNE_T_DEFINED_ +#define _BSD_CT_RUNE_T_DEFINED_ +typedef _BSD_CT_RUNE_T_ ct_rune_t; +#endif + +#ifndef _BSD_RUNE_T_DEFINED_ +#define _BSD_RUNE_T_DEFINED_ +typedef _BSD_RUNE_T_ rune_t; +#endif + +#ifndef __cplusplus #ifndef _BSD_WCHAR_T_DEFINED_ -#define _BSD_WCHAR_T_DEFINED_ +#define _BSD_WCHAR_T_DEFINED_ +#ifdef __WCHAR_TYPE__ +typedef __WCHAR_TYPE__ wchar_t; +#else /* ! __WCHAR_TYPE__ */ typedef _BSD_WCHAR_T_ wchar_t; +#endif /* __WCHAR_TYPE__ */ +#endif /* _BSD_WCHAR_T_DEFINED_ */ +#endif /* __cplusplus */ + +#ifndef _BSD_WINT_T_DEFINED_ +#define _BSD_WINT_T_DEFINED_ +typedef _BSD_WINT_T_ wint_t; #endif #define _CACHED_RUNES (1 <<8 ) /* Must be a power of 2 */ @@ -80,9 +96,9 @@ typedef struct { char encoding[32]; /* ASCII name of this encoding */ rune_t (*sgetrune) - __P((const char *, size_t, char const **)); + (const char *, size_t, char const **); int (*sputrune) - __P((rune_t, char *, size_t, char **)); + (rune_t, char *, size_t, char **); rune_t invalid_rune; unsigned long runetype[_CACHED_RUNES]; @@ -104,7 +120,9 @@ typedef struct { #define _RUNE_MAGIC_1 "RuneMagi" /* Indicates version 0 of RuneLocale */ +__BEGIN_DECLS extern _RuneLocale _DefaultRuneLocale; extern _RuneLocale *_CurrentRuneLocale; +__END_DECLS #endif /* !_RUNETYPE_H_ */ diff --git a/include/search.h b/include/search.h new file mode 100644 index 0000000..aa21d8b --- /dev/null +++ b/include/search.h @@ -0,0 +1,61 @@ +/*- + * Written by J.T. Conklin + * Public domain. + * + * $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ + * $FreeBSD: src/include/search.h,v 1.10 2002/10/16 14:29:23 robert Exp $ + */ + +#ifndef _SEARCH_H_ +#define _SEARCH_H_ + +#include +#include + +typedef struct entry { + char *key; + void *data; +} ENTRY; + +typedef enum { + FIND, ENTER +} ACTION; + +typedef enum { + preorder, + postorder, + endorder, + leaf +} VISIT; + +#ifdef _SEARCH_PRIVATE +typedef struct node { + char *key; + struct node *llink, *rlink; +} node_t; + +struct que_elem { + struct que_elem *next; + struct que_elem *prev; +}; +#endif + +__BEGIN_DECLS +int hcreate(size_t); +void hdestroy(void); +ENTRY *hsearch(ENTRY, ACTION); +void insque(void *, void *); +void *lfind(const void *, const void *, size_t *, size_t, + int (*)(const void *, const void *)); +void *lsearch(const void *, void *, size_t *, size_t, + int (*)(const void *, const void *)); +void remque(void *); +void *tdelete(const void * __restrict, void ** __restrict, + int (*)(const void *, const void *)); +void *tfind(const void *, void * const *, + int (*)(const void *, const void *)); +void *tsearch(const void *, void **, int (*)(const void *, const void *)); +void twalk(const void *, void (*)(const void *, VISIT, int)); +__END_DECLS + +#endif /* !_SEARCH_H_ */ diff --git a/include/signal.h b/include/signal.h index 8f7fa38..8707e2d 100644 --- a/include/signal.h +++ b/include/signal.h @@ -70,29 +70,32 @@ extern __const char *__const sys_siglist[NSIG]; #endif __BEGIN_DECLS -int raise __P((int)); +int raise(int); #ifndef _ANSI_SOURCE -int kill __P((pid_t, int)); -int sigaction __P((int, const struct sigaction *, struct sigaction *)); -int sigaddset __P((sigset_t *, int)); -int sigdelset __P((sigset_t *, int)); -int sigemptyset __P((sigset_t *)); -int sigfillset __P((sigset_t *)); -int sigismember __P((const sigset_t *, int)); -int sigpending __P((sigset_t *)); -int sigprocmask __P((int, const sigset_t *, sigset_t *)); -int sigsuspend __P((const sigset_t *)); +int kill(pid_t, int); +int sigaction(int, const struct sigaction *, struct sigaction *); +int sigaddset(sigset_t *, int); +int sigaltstack(const struct sigaltstack *, struct sigaltstack *); +int sigdelset(sigset_t *, int); +int sigemptyset(sigset_t *); +int sigfillset(sigset_t *); +int sigismember(const sigset_t *, int); +int sigpending(sigset_t *); +int sigprocmask(int, const sigset_t *, sigset_t *); +int sigsuspend(const sigset_t *); +int sigwait(const sigset_t *, int *); #ifndef _POSIX_SOURCE -int killpg __P((pid_t, int)); -int sigblock __P((int)); -int siginterrupt __P((int, int)); -int sighold __P((int)); -int sigrelse __P((int)); -int sigpause __P((int)); -int sigreturn __P((struct sigcontext *)); -int sigsetmask __P((int)); -int sigvec __P((int, struct sigvec *, struct sigvec *)); -void psignal __P((unsigned int, const char *)); +int killpg(pid_t, int); +int sigblock(int); +int siginterrupt(int, int); +int sighold(int); +int sigrelse(int); +int sigpause(int); +int sigreturn(struct sigcontext *); +int sigsetmask(int); +int sigvec(int, struct sigvec *, struct sigvec *); +void psignal(unsigned int, const char *); + #endif /* !_POSIX_SOURCE */ #endif /* !_ANSI_SOURCE */ __END_DECLS diff --git a/include/standards.h b/include/standards.h index b61eb11..d24b8e1 100644 --- a/include/standards.h +++ b/include/standards.h @@ -30,10 +30,10 @@ #define _STANDARDS_H #ifdef _POSIX_SOURCE - #ifndef __STRICT_ANSI__ - #define __STRICT_ANSI__ - #endif - #undef __STRICT_BSD__ +# ifndef __STRICT_ANSI__ +# define __STRICT_ANSI__ +# endif +# undef __STRICT_BSD__ #endif /* _POSIX_SOURCE */ #endif /* _STANDARDS_H */ diff --git a/include/stddef.h b/include/stddef.h index 47c8898..b7ae6fb 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -73,16 +73,30 @@ typedef _BSD_PTRDIFF_T_ ptrdiff_t; typedef _BSD_SIZE_T_ size_t; #endif -#if !defined(_ANSI_SOURCE) -#ifndef _BSD_RUNE_T_DEFINED_ -#define _BSD_RUNE_T_DEFINED_ -typedef _BSD_RUNE_T_ rune_t; +#ifndef _BSD_CT_RUNE_T_DEFINED_ +#define _BSD_CT_RUNE_T_DEFINED_ +typedef _BSD_CT_RUNE_T_ ct_rune_t; #endif + +#ifndef _BSD_RUNE_T_DEFINED_ +#define _BSD_RUNE_T_DEFINED_ +typedef _BSD_RUNE_T_ rune_t; #endif +#ifndef __cplusplus #ifndef _BSD_WCHAR_T_DEFINED_ #define _BSD_WCHAR_T_DEFINED_ +#ifdef __WCHAR_TYPE__ +typedef __WCHAR_TYPE__ wchar_t; +#else /* ! __WCHAR_TYPE__ */ typedef _BSD_WCHAR_T_ wchar_t; +#endif /* __WCHAR_TYPE__ */ +#endif /* _BSD_WCHAR_T_DEFINED_ */ +#endif /* __cplusplus */ + +#ifndef _BSD_WINT_T_DEFINED_ +#define _BSD_WINT_T_DEFINED_ +typedef _BSD_WINT_T_ wint_t; #endif #ifndef NULL diff --git a/include/stdio.h b/include/stdio.h index bd7af4f..4c365f9 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -79,23 +79,11 @@ typedef _BSD_SIZE_T_ size_t; #define NULL 0 #endif -/* - * This is fairly grotesque, but pure ANSI code must not inspect the - * innards of an fpos_t anyway. The library internally uses off_t, - * which we assume is exactly as big as eight chars. (When we switch - * to gcc 2.4 we will use __attribute__ here.) - * - * WARNING: the alignment constraints on an off_t and the struct below - * differ on (e.g.) the SPARC. Hence, the placement of an fpos_t object - * in a structure will change if fpos_t's are not aligned on 8-byte - * boundaries. THIS IS A CROCK, but for now there is no way around it. - */ #if !defined(_ANSI_SOURCE) && !defined(__STRICT_ANSI__) typedef off_t fpos_t; #else -typedef struct __sfpos { - char _pos[8]; -} fpos_t; +#include +typedef int64_t fpos_t; #endif #define _FSTDIO /* Define for new stdio with functions. */ @@ -112,6 +100,9 @@ struct __sbuf { int _size; }; +/* hold a buncha junk that would grow the ABI */ +struct __sFILEX; + /* * stdio state variables. * @@ -149,14 +140,14 @@ typedef struct __sFILE { /* operations */ void *_cookie; /* cookie passed to io functions */ - int (*_close) __P((void *)); - int (*_read) __P((void *, char *, int)); - fpos_t (*_seek) __P((void *, fpos_t, int)); - int (*_write) __P((void *, const char *, int)); + int (*_close)(void *); + int (*_read) (void *, char *, int); + fpos_t (*_seek) (void *, fpos_t, int); + int (*_write)(void *, const char *, int); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ - unsigned char *_up; /* saved _p when _p is doing ungetc data */ + struct __sFILEX *_extra; /* additions to FILE to not break ABI */ int _ur; /* saved _r when _r is counting ungetc data */ /* tricks to meet minimum requirements even when malloc() fails */ @@ -191,6 +182,7 @@ __END_DECLS #define __SOFF 0x1000 /* set iff _offset is in fact correct */ #define __SMOD 0x2000 /* true => fgetln modified _p text */ #define __SALC 0x4000 /* allocate string space dynamically */ +#define __SIGN 0x8000 /* ignore this file in _fwalk */ /* * The following three definitions are for ANSI C, which took them @@ -242,53 +234,53 @@ __END_DECLS * Functions defined in ANSI C standard. */ __BEGIN_DECLS -void clearerr __P((FILE *)); -int fclose __P((FILE *)); -int feof __P((FILE *)); -int ferror __P((FILE *)); -int fflush __P((FILE *)); -int fgetc __P((FILE *)); -int fgetpos __P((FILE *, fpos_t *)); -char *fgets __P((char *, int, FILE *)); -FILE *fopen __P((const char *, const char *)); -int fprintf __P((FILE *, const char *, ...)); -int fputc __P((int, FILE *)); -int fputs __P((const char *, FILE *)); -size_t fread __P((void *, size_t, size_t, FILE *)); -FILE *freopen __P((const char *, const char *, FILE *)); -int fscanf __P((FILE *, const char *, ...)); -int fseek __P((FILE *, long, int)); -int fsetpos __P((FILE *, const fpos_t *)); -long ftell __P((FILE *)); -size_t fwrite __P((const void *, size_t, size_t, FILE *)); -int getc __P((FILE *)); -int getchar __P((void)); -char *gets __P((char *)); +void clearerr(FILE *); +int fclose(FILE *); +int feof(FILE *); +int ferror(FILE *); +int fflush(FILE *); +int fgetc(FILE *); +int fgetpos(FILE *, fpos_t *); +char *fgets(char *, int, FILE *); +FILE *fopen(const char *, const char *); +int fprintf(FILE *, const char *, ...); +int fputc(int, FILE *); +int fputs(const char *, FILE *); +size_t fread(void *, size_t, size_t, FILE *); +FILE *freopen(const char *, const char *, FILE *); +int fscanf(FILE *, const char *, ...); +int fseek(FILE *, long, int); +int fsetpos(FILE *, const fpos_t *); +long ftell(FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); +int getc(FILE *); +int getchar(void); +char *gets(char *); #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) extern __const int sys_nerr; /* perror(3) external variables */ extern __const char *__const sys_errlist[]; #endif -void perror __P((const char *)); -int printf __P((const char *, ...)); -int putc __P((int, FILE *)); -int putchar __P((int)); -int puts __P((const char *)); -int remove __P((const char *)); -int rename __P((const char *, const char *)); -void rewind __P((FILE *)); -int scanf __P((const char *, ...)); -void setbuf __P((FILE *, char *)); -int setvbuf __P((FILE *, char *, int, size_t)); -int sprintf __P((char *, const char *, ...)); -int sscanf __P((const char *, const char *, ...)); -FILE *tmpfile __P((void)); -char *tmpnam __P((char *)); -int ungetc __P((int, FILE *)); -int vfprintf __P((FILE *, const char *, _BSD_VA_LIST_)); -int vprintf __P((const char *, _BSD_VA_LIST_)); -int vsprintf __P((char *, const char *, _BSD_VA_LIST_)); -int asprintf __P((char **, const char *, ...)); -int vasprintf __P((char **, const char *, _BSD_VA_LIST_)); +void perror(const char *); +int printf(const char *, ...); +int putc(int, FILE *); +int putchar(int); +int puts(const char *); +int remove(const char *); +int rename (const char *, const char *); +void rewind(FILE *); +int scanf(const char *, ...); +void setbuf(FILE *, char *); +int setvbuf(FILE *, char *, int, size_t); +int sprintf(char *, const char *, ...); +int sscanf(const char *, const char *, ...); +FILE *tmpfile(void); +char *tmpnam(char *); +int ungetc(int, FILE *); +int vfprintf(FILE *, const char *, _BSD_VA_LIST_); +int vprintf(const char *, _BSD_VA_LIST_); +int vsprintf(char *, const char *, _BSD_VA_LIST_); +int asprintf(char **, const char *, ...); +int vasprintf(char **, const char *, _BSD_VA_LIST_); __END_DECLS /* @@ -299,9 +291,10 @@ __END_DECLS #define L_ctermid 1024 /* size for ctermid(); PATH_MAX */ __BEGIN_DECLS -char *ctermid __P((char *)); -FILE *fdopen __P((int, const char *)); -int fileno __P((FILE *)); +char *ctermid(char *); +char *ctermid_r(char *); +FILE *fdopen(int, const char *); +int fileno(FILE *); __END_DECLS #endif /* not ANSI */ @@ -310,40 +303,43 @@ __END_DECLS */ #if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE) __BEGIN_DECLS -char *fgetln __P((FILE *, size_t *)); -int fpurge __P((FILE *)); -int fseeko __P((FILE *, fpos_t, int)); -fpos_t ftello __P((FILE *)); -int getw __P((FILE *)); -int pclose __P((FILE *)); -FILE *popen __P((const char *, const char *)); -int putw __P((int, FILE *)); -void setbuffer __P((FILE *, char *, int)); -int setlinebuf __P((FILE *)); -char *tempnam __P((const char *, const char *)); -int snprintf __P((char *, size_t, const char *, ...)); -int vsnprintf __P((char *, size_t, const char *, _BSD_VA_LIST_)); -int vscanf __P((const char *, _BSD_VA_LIST_)); -int vsscanf __P((const char *, const char *, _BSD_VA_LIST_)); -FILE *zopen __P((const char *, const char *, int)); +char *fgetln(FILE *, size_t *); +void flockfile(FILE *); +__const char + *fmtcheck(const char *, const char *); +int fpurge(FILE *); +int fseeko(FILE *, fpos_t, int); +fpos_t ftello(FILE *); +int ftrylockfile(FILE *); +void funlockfile(FILE *); +int getc_unlocked(FILE *); +int getchar_unlocked(void); +int getw(FILE *); +int pclose(FILE *); +FILE *popen(const char *, const char *); +int putc_unlocked(int, FILE *); +int putchar_unlocked(int); +int putw(int, FILE *); +void setbuffer(FILE *, char *, int); +int setlinebuf(FILE *); +char *tempnam(const char *, const char *); +int snprintf(char *, size_t, const char *, ...); +int vfscanf(FILE *, const char *, _BSD_VA_LIST_); +int vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_); +int vscanf(const char *, _BSD_VA_LIST_); +int vsscanf(const char *, const char *, _BSD_VA_LIST_); +FILE *zopen(const char *, const char *, int); __END_DECLS -/* - * This is a #define because the function is used internally and - * (unlike vfscanf) the name __svfscanf is guaranteed not to collide - * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined. - */ -#define vfscanf __svfscanf - /* * Stdio function-access interface. */ __BEGIN_DECLS -FILE *funopen __P((const void *, +FILE *funopen(const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), fpos_t (*)(void *, fpos_t, int), - int (*)(void *))); + int (*)(void *)); __END_DECLS #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) @@ -353,9 +349,9 @@ __END_DECLS * Functions internal to the implementation. */ __BEGIN_DECLS -int __srget __P((FILE *)); -int __svfscanf __P((FILE *, const char *, _BSD_VA_LIST_)); -int __swbuf __P((int, FILE *)); +int __srget(FILE *); +int __svfscanf(FILE *, const char *, _BSD_VA_LIST_); +int __swbuf(int, FILE *); __END_DECLS /* @@ -389,19 +385,19 @@ static __inline int __sputc(int _c, FILE *_p) { #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sfileno(p) ((p)->_file) -#define feof(p) __sfeof(p) -#define ferror(p) __sferror(p) -#define clearerr(p) __sclearerr(p) +#define feof_unlocked(p) __sfeof(p) +#define ferror_unlocked(p) __sferror(p) +#define clearerr_unlocked(p) __sclearerr(p) #ifndef _ANSI_SOURCE -#define fileno(p) __sfileno(p) +#define fileno_unlocked(p) __sfileno(p) #endif #ifndef lint -#define getc(fp) __sgetc(fp) -#define putc(x, fp) __sputc(x, fp) +#define getc_unlocked(fp) __sgetc(fp) +#define putc_unlocked(x, fp) __sputc(x, fp) #endif /* lint */ -#define getchar() getc(stdin) -#define putchar(x) putc(x, stdout) +#define getchar_unlocked() getc_unlocked(stdin) +#define putchar_unlocked(x) putc_unlocked(x, stdout) #endif /* _STDIO_H_ */ diff --git a/include/stdlib.h b/include/stdlib.h index 08c9bc7..485d027 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -62,6 +62,9 @@ #include #include +#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) +#include +#endif #ifndef _BSD_SIZE_T_DEFINED_ #define _BSD_SIZE_T_DEFINED_ @@ -69,15 +72,31 @@ typedef _BSD_SIZE_T_ size_t; #endif #if !defined(_ANSI_SOURCE) +#ifndef _BSD_CT_RUNE_T_DEFINED_ +#define _BSD_CT_RUNE_T_DEFINED_ +typedef _BSD_CT_RUNE_T_ ct_rune_t; +#endif + #ifndef _BSD_RUNE_T_DEFINED_ #define _BSD_RUNE_T_DEFINED_ -typedef _BSD_WCHAR_T_ rune_t; +typedef _BSD_RUNE_T_ rune_t; #endif #endif +#ifndef __cplusplus #ifndef _BSD_WCHAR_T_DEFINED_ #define _BSD_WCHAR_T_DEFINED_ +#ifdef __WCHAR_TYPE__ +typedef __WCHAR_TYPE__ wchar_t; +#else /* ! __WCHAR_TYPE__ */ typedef _BSD_WCHAR_T_ wchar_t; +#endif /* __WCHAR_TYPE__ */ +#endif /* _BSD_WCHAR_T_DEFINED_ */ +#endif /* __cplusplus */ + +#ifndef _BSD_WINT_T_DEFINED_ +#define _BSD_WINT_T_DEFINED_ +typedef _BSD_WINT_T_ wint_t; #endif typedef struct { @@ -105,116 +124,130 @@ extern int __mb_cur_max; #include __BEGIN_DECLS -__dead void - abort __P((void)); -__pure int - abs __P((int)); -int atexit __P((void (*)(void))); -double atof __P((const char *)); -int atoi __P((const char *)); -long atol __P((const char *)); -void *bsearch __P((const void *, const void *, size_t, - size_t, int (*)(const void *, const void *))); -void *calloc __P((size_t, size_t)); -__pure div_t - div __P((int, int)); -__dead void - exit __P((int)); -void free __P((void *)); -char *getenv __P((const char *)); -__pure long - labs __P((long)); -__pure ldiv_t - ldiv __P((long, long)); -void *malloc __P((size_t)); -void qsort __P((void *, size_t, size_t, - int (*)(const void *, const void *))); -int rand __P((void)); -void *realloc __P((void *, size_t)); -void srand __P((unsigned)); -double strtod __P((const char *, char **)); -long strtol __P((const char *, char **, int)); +void abort(void) __dead2; +int abs(int) __pure2; +int atexit(void (*)(void)); +double atof(const char *); +int atoi(const char *); +long atol(const char *); +void *bsearch(const void *, const void *, size_t, + size_t, int (*)(const void *, const void *)); +void *calloc(size_t, size_t); +div_t div(int, int) __pure2; +void exit(int) __dead2; +void free(void *); +char *getenv(const char *); +long labs(long) __pure2; +ldiv_t ldiv(long, long) __pure2; +void *malloc(size_t); +int mblen(const char *, size_t); +size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); +int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); +void qsort(void *, size_t, size_t, + int (*)(const void *, const void *)); +int rand(void); +void *realloc(void *, size_t); +void srand(unsigned); +double strtod(const char *, char **); +float strtof(const char *, char **); +long strtol(const char *, char **, int); +long double + strtold(const char *, char **); unsigned long - strtoul __P((const char *, char **, int)); -int system __P((const char *)); - -/* These are currently just stubs. */ -int mblen __P((const char *, size_t)); -size_t mbstowcs __P((wchar_t *, const char *, size_t)); -int wctomb __P((char *, wchar_t)); -int mbtowc __P((wchar_t *, const char *, size_t)); -size_t wcstombs __P((char *, const wchar_t *, size_t)); + strtoul(const char *, char **, int); +int system(const char *); +void *valloc(size_t); +int wctomb(char *, wchar_t); +size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); #ifndef _ANSI_SOURCE -int putenv __P((const char *)); -int setenv __P((const char *, const char *, int)); +int putenv(const char *); +int setenv(const char *, const char *, int); #endif #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) -double drand48 __P((void)); -double erand48 __P((unsigned short[3])); -long jrand48 __P((unsigned short[3])); -void lcong48 __P((unsigned short[7])); -long lrand48 __P((void)); -long mrand48 __P((void)); -long nrand48 __P((unsigned short[3])); -unsigned short - *seed48 __P((unsigned short[3])); -void srand48 __P((long)); - -void *alloca __P((size_t)); /* built-in for gcc */ - /* getcap(3) functions */ u_int32_t - arc4random __P((void)); -void arc4random_addrandom __P((unsigned char *dat, int datlen)); -void arc4random_stir __P((void)); -char *getbsize __P((int *, long *)); -char *cgetcap __P((char *, char *, int)); -int cgetclose __P((void)); -int cgetent __P((char **, char **, char *)); -int cgetfirst __P((char **, char **)); -int cgetmatch __P((char *, char *)); -int cgetnext __P((char **, char **)); -int cgetnum __P((char *, char *, long *)); -int cgetset __P((char *)); -int cgetstr __P((char *, char *, char **)); -int cgetustr __P((char *, char *, char **)); - -int daemon __P((int, int)); -char *devname __P((int, int)); -int getloadavg __P((double [], int)); - -long a64l __P((const char *)); -char *l64a __P((long)); - -char *group_from_gid __P((unsigned long, int)); -int heapsort __P((void *, size_t, size_t, - int (*)(const void *, const void *))); -char *initstate __P((unsigned long, char *, long)); -int mergesort __P((void *, size_t, size_t, - int (*)(const void *, const void *))); -int radixsort __P((const unsigned char **, int, const unsigned char *, - unsigned)); -int sradixsort __P((const unsigned char **, int, const unsigned char *, - unsigned)); -int rand_r __P((unsigned *)); -long random __P((void)); -void *reallocf __P((void *, size_t)); -char *realpath __P((const char *, char resolved_path[])); -char *setstate __P((char *)); -void srandom __P((unsigned long)); -char *user_from_uid __P((unsigned long, int)); + arc4random(void); +void arc4random_addrandom(unsigned char *dat, int datlen); +void arc4random_stir(void); +double drand48(void); +double erand48(unsigned short[3]); +long jrand48(unsigned short[3]); +void lcong48(unsigned short[7]); +long lrand48(void); +long mrand48(void); +long nrand48(unsigned short[3]); +unsigned short + *seed48(unsigned short[3]); +void srand48(long); + + /* getcap(3) functions */ +char *cgetcap(char *, const char *, int); +int cgetclose(void); +int cgetent(char **, char **, const char *); +int cgetfirst(char **, char **); +int cgetmatch(const char *, const char *); +int cgetnext(char **, char **); +int cgetnum(char *, const char *, long *); +int cgetset(const char *); +int cgetstr(char *, const char *, char **); +int cgetustr(char *, const char *, char **); + +int daemon(int, int); +char *devname(int, int); +char *getbsize(int *, long *); +int getloadavg(double [], int); +const char + *getprogname(void); + +long a64l(const char *); +char *l64a(long); + +/* int grantpt(int); */ +int heapsort(void *, size_t, size_t, + int (*)(const void *, const void *)); +char *initstate(unsigned long, char *, long); +int mergesort(void *, size_t, size_t, + int (*)(const void *, const void *)); +/* int posix_openpt(int); */ +/* char *ptsname(int); */ +void qsort_r(void *, size_t, size_t, void *, + int (*)(void *, const void *, const void *)); +int radixsort(const unsigned char **, int, const unsigned char *, + unsigned); +void setprogname(const char *); +int sradixsort(const unsigned char **, int, const unsigned char *, + unsigned); +void sranddev(void); +void srandomdev(void); +int rand_r(unsigned *); +long random(void); +void *reallocf(void *, size_t); +char *realpath(const char *, char resolved_path[]); +char *setstate(char *); +void srandom(unsigned long); +/* int unlockpt(int); */ #ifndef __STRICT_ANSI__ +typedef struct { + long long quot; + long long rem; +} lldiv_t; + +long long + atoll(const char *); +long long + llabs(long long); +lldiv_t lldiv(long long, long long); long long strtoll(const char *, char **, int); unsigned long long strtoull(const char *, char **, int); long long - strtoq __P((const char *, char **, int)); + strtoq(const char *, char **, int); unsigned long long - strtouq __P((const char *, char **, int)); + strtouq(const char *, char **, int); #endif -void unsetenv __P((const char *)); +void unsetenv(const char *); #endif __END_DECLS diff --git a/include/strhash.h b/include/strhash.h new file mode 100644 index 0000000..f8fa55a --- /dev/null +++ b/include/strhash.h @@ -0,0 +1,68 @@ +#ifndef _STRHASH_H_INCLUDE +#define _STRHASH_H_INCLUDE + +/* $FreeBSD: /repoman/r/ncvs/src/include/strhash.h,v 1.3 1999/08/28 04:59:30 peter Exp $ */ + +/* + * + * 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 the definition file for hash.c. The plunderer from down-under + * did the code, I just helped define the spec. That's why his name gets + * to go first. + */ + +#define HASH_SZ 97 + +typedef struct _node { + char *key; + void *data; + struct _node *next; +} hash_node; + +typedef struct { + int size; + hash_node **buckets; +} hash_table; + +#include + +__BEGIN_DECLS +hash_table *hash_create(int size); +void hash_destroy(hash_table *table, char *key, + void (*nukefunc)(char *k, void *d)); +void *hash_search(hash_table *table, char *key, void *datum, + void (*replace_func)(void *d)); +void hash_traverse(hash_table *table, + int (*func)(char *k, void *d, void *arg), void *arg); +void hash_purge(hash_table *table, void (*purge_func)(char *k, void *d)); + +#ifdef HASH_STATS +extern void hash_stats(); +#endif +__END_DECLS + +#endif /* _STRHASH_H_INCLUDE */ diff --git a/include/string.h b/include/string.h index aabb118..9a62832 100644 --- a/include/string.h +++ b/include/string.h @@ -73,47 +73,52 @@ typedef _BSD_SIZE_T_ size_t; #include __BEGIN_DECLS -void *memchr __P((const void *, int, size_t)); -int memcmp __P((const void *, const void *, size_t)); -void *memcpy __P((void *, const void *, size_t)); -void *memmove __P((void *, const void *, size_t)); -void *memset __P((void *, int, size_t)); -char *strcat __P((char *, const char *)); -char *strchr __P((const char *, int)); -int strcmp __P((const char *, const char *)); -int strcoll __P((const char *, const char *)); -char *strcpy __P((char *, const char *)); -size_t strcspn __P((const char *, const char *)); -char *strerror __P((int)); -size_t strlen __P((const char *)); -char *strncat __P((char *, const char *, size_t)); -int strncmp __P((const char *, const char *, size_t)); -char *strncpy __P((char *, const char *, size_t)); -char *strpbrk __P((const char *, const char *)); -char *strrchr __P((const char *, int)); -size_t strspn __P((const char *, const char *)); -char *strstr __P((const char *, const char *)); -char *strtok __P((char *, const char *)); -size_t strxfrm __P((char *, const char *, size_t)); +void *memchr(const void *, int, size_t); +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); +char *stpcpy(char *, const char *); +char *strcasestr(const char *, const char *); +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); +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); +char *strnstr(const char *, const char *, size_t); +char *strpbrk(const char *, const char *); +char *strrchr(const char *, int); +size_t strspn(const char *, const char *); +char *strstr(const char *, const char *); +char *strtok(char *, const char *); +size_t strxfrm(char *, const char *, size_t); /* Nonstandard routines */ #ifndef _ANSI_SOURCE -int bcmp __P((const void *, const void *, size_t)); -void bcopy __P((const void *, void *, size_t)); -void bzero __P((void *, size_t)); -int ffs __P((int)); -char *index __P((const char *, int)); -void *memccpy __P((void *, const void *, int, size_t)); -char *rindex __P((const char *, int)); -int strcasecmp __P((const char *, const char *)); -char *strdup __P((const char *)); -size_t strlcat __P((char *, const char *, size_t)); -size_t strlcpy __P((char *, const char *, size_t)); -void strmode __P((int, char *)); -int strncasecmp __P((const char *, const char *, size_t)); -char *strsep __P((char **, const char *)); -char *strtok_r __P((char *, const char *, char **)); -void swab __P((const void *, void *, size_t)); +int bcmp(const void *, const void *, size_t); +void bcopy(const void *, void *, size_t); +void bzero(void *, size_t); +int ffs(int); +char *index(const char *, int); +void *memccpy(void *, const void *, int, size_t); +char *rindex(const char *, int); +int strcasecmp(const char *, const char *); +char *strdup(const char *); +size_t strlcat(char *, const char *, size_t); +size_t strlcpy(char *, const char *, size_t); +void strmode(int, char *); +int strncasecmp(const char *, const char *, size_t); +char *strsep(char **, const char *); +char *strsignal(int sig); +char *strtok_r(char *, const char *, char **); +void swab(const void *, void *, size_t); #endif __END_DECLS diff --git a/include/stringlist.h b/include/stringlist.h new file mode 100644 index 0000000..7f2925a --- /dev/null +++ b/include/stringlist.h @@ -0,0 +1,57 @@ +/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */ + +/* + * 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. + * + * $FreeBSD: /repoman/r/ncvs/src/include/stringlist.h,v 1.3 2003/01/19 01:16:00 obrien Exp $ + */ + +#ifndef _STRINGLIST_H +#define _STRINGLIST_H +#include +#include + +/* + * Simple string list + */ +typedef struct _stringlist { + char **sl_str; + size_t sl_max; + size_t sl_cur; +} StringList; + +__BEGIN_DECLS +StringList *sl_init(void); +int sl_add(StringList *, char *); +void sl_free(StringList *, int); +char *sl_find(StringList *, char *); +__END_DECLS + +#endif /* _STRINGLIST_H */ diff --git a/include/time.h b/include/time.h index accf748..79b2f96 100644 --- a/include/time.h +++ b/include/time.h @@ -119,34 +119,36 @@ extern char *tzname[]; #endif __BEGIN_DECLS -char *asctime __P((const struct tm *)); -clock_t clock __P((void)); -char *ctime __P((const time_t *)); -double difftime __P((time_t, time_t)); -struct tm *gmtime __P((const time_t *)); -struct tm *localtime __P((const time_t *)); -time_t mktime __P((struct tm *)); -size_t strftime __P((char *, size_t, const char *, const struct tm *)); -time_t time __P((time_t *)); +char *asctime(const struct tm *); +clock_t clock(void); +char *ctime(const time_t *); +double difftime(time_t, time_t); +struct tm *gmtime(const time_t *); +struct tm *localtime(const time_t *); +time_t mktime(struct tm *); +size_t strftime(char *, size_t, const char *, const struct tm *); +time_t time(time_t *); #ifndef _ANSI_SOURCE -void tzset __P((void)); +void tzset(void); #endif /* not ANSI */ #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) -char *asctime_r __P((const struct tm *, char *)); -char *ctime_r __P((const time_t *, char *)); -struct tm *gmtime_r __P((const time_t *, struct tm *)); -struct tm *localtime_r __P((const time_t *, struct tm *)); -char *strptime __P((const char *, const char *, struct tm *)); -char *timezone __P((int, int)); -void tzsetwall __P((void)); -time_t timelocal __P((struct tm * const)); -time_t timegm __P((struct tm * const)); +char *asctime_r(const struct tm *, char *); +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 *); +time_t posix2time(time_t); +char *strptime(const char *, const char *, struct tm *); +char *timezone(int, int); +void tzsetwall(void); +time_t time2posix(time_t); +time_t timelocal(struct tm * const); +time_t timegm(struct tm * const); #endif /* neither ANSI nor POSIX */ #if !defined(_ANSI_SOURCE) -int nanosleep __P((const struct timespec *, struct timespec *)); +int nanosleep(const struct timespec *, struct timespec *); #endif __END_DECLS diff --git a/gen/difftime.c b/include/timeconv.h similarity index 62% rename from gen/difftime.c rename to include/timeconv.h index 5c648f9..2310e33 100644 --- a/gen/difftime.c +++ b/include/timeconv.h @@ -1,30 +1,11 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,14 +34,29 @@ * LIABILITY, OR TORT (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.h 8.3 (Berkeley) 1/21/94 */ +/* + * $FreeBSD: /repoman/r/ncvs/src/include/timeconv.h,v 1.2 2002/08/21 16:19:55 mike Exp $ + */ +#ifndef _TIMECONV_H_ +#define _TIMECONV_H_ + +#include #include -double -difftime(time1, time0) - time_t time1, time0; -{ - return(time1 - time0); -} +__BEGIN_DECLS +time_t _time32_to_time(int32_t t32); +int32_t _time_to_time32(time_t t); +time_t _time64_to_time(int64_t t64); +int64_t _time_to_time64(time_t t); +long _time_to_long(time_t t); +time_t _long_to_time(long tlong); +int _time_to_int(time_t t); +time_t _int_to_time(int tint); +__END_DECLS + +#endif /* _TIMECONV_H_ */ diff --git a/include/ttyent.h b/include/ttyent.h index 449e93e..9e56ce7 100644 --- a/include/ttyent.h +++ b/include/ttyent.h @@ -85,10 +85,10 @@ struct ttyent { #include __BEGIN_DECLS -struct ttyent *getttyent __P((void)); -struct ttyent *getttynam __P((const char *)); -int setttyent __P((void)); -int endttyent __P((void)); +struct ttyent *getttyent(void); +struct ttyent *getttynam(const char *); +int setttyent(void); +int endttyent(void); __END_DECLS #endif /* !_TTYENT_H_ */ diff --git a/include/ulimit.h b/include/ulimit.h index 55bb1a2..d50ada5 100644 --- a/include/ulimit.h +++ b/include/ulimit.h @@ -4,6 +4,10 @@ #define UL_GETFSIZE 1 #define UL_SETFSIZE 2 +#include + +__BEGIN_DECLS long int ulimit(int, ...); +__END_DECLS #endif /* _ULIMIT_H */ diff --git a/include/unistd.h b/include/unistd.h index 0f2a70b..2bec594 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -91,159 +91,202 @@ #define F_TEST 3 /* test a section for locks by other procs */ #endif +/* configurable system variables */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _SC_CLK_TCK 3 +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 +#define _SC_BC_BASE_MAX 9 +#define _SC_BC_DIM_MAX 10 +#define _SC_BC_SCALE_MAX 11 +#define _SC_BC_STRING_MAX 12 +#define _SC_COLL_WEIGHTS_MAX 13 +#define _SC_EXPR_NEST_MAX 14 +#define _SC_LINE_MAX 15 +#define _SC_RE_DUP_MAX 16 +#define _SC_2_VERSION 17 +#define _SC_2_C_BIND 18 +#define _SC_2_C_DEV 19 +#define _SC_2_CHAR_TERM 20 +#define _SC_2_FORT_DEV 21 +#define _SC_2_FORT_RUN 22 +#define _SC_2_LOCALEDEF 23 +#define _SC_2_SW_DEV 24 +#define _SC_2_UPE 25 +#define _SC_STREAM_MAX 26 +#define _SC_TZNAME_MAX 27 +/* POSIX.1B sysconf options for async IO*/ +#define _SC_ASYNCHRONOUS_IO 28 +#define _SC_PAGESIZE 29 +#define _SC_AIO_LISTIO_MAX 42 +#define _SC_AIO_MAX 43 +#define _SC_AIO_PRIO_DELTA_MAX 44 + __BEGIN_DECLS -__dead void - _exit __P((int)); -int access __P((const char *, int)); -unsigned int alarm __P((unsigned int)); -int chdir __P((const char *)); -int chown __P((const char *, uid_t, gid_t)); -int close __P((int)); -size_t confstr __P((int, char *, size_t)); -int dup __P((int)); -int dup2 __P((int, int)); -int execl __P((const char *, const char *, ...)); -int execle __P((const char *, const char *, ...)); -int execlp __P((const char *, const char *, ...)); -int execv __P((const char *, char * const *)); -int execve __P((const char *, char * const *, char * const *)); -int execvp __P((const char *, char * const *)); -pid_t fork __P((void)); -long fpathconf __P((int, int)); -char *getcwd __P((char *, size_t)); -gid_t getegid __P((void)); -uid_t geteuid __P((void)); -gid_t getgid __P((void)); -int getgroups __P((int, gid_t [])); -char *getlogin __P((void)); -pid_t getpgrp __P((void)); -pid_t getpid __P((void)); -pid_t getppid __P((void)); -uid_t getuid __P((void)); -int isatty __P((int)); -int link __P((const char *, const char *)); -off_t lseek __P((int, off_t, int)); -long pathconf __P((const char *, int)); -int pause __P((void)); -int pipe __P((int *)); -ssize_t read __P((int, void *, size_t)); -int rmdir __P((const char *)); -int setgid __P((gid_t)); -int setpgid __P((pid_t, pid_t)); -pid_t setsid __P((void)); -int setuid __P((uid_t)); -unsigned int sleep __P((unsigned int)); -long sysconf __P((int)); -pid_t tcgetpgrp __P((int)); -int tcsetpgrp __P((int, pid_t)); -char *ttyname __P((int)); -int unlink __P((const char *)); -ssize_t write __P((int, const void *, size_t)); + +void _Exit(int) __dead2; +void _exit(int) __dead2; +int access(const char *, int); +unsigned int alarm(unsigned int); +int chdir(const char *); +int chown(const char *, uid_t, gid_t); +int close(int); +size_t confstr(int, char *, size_t); +int dup(int); +int dup2(int, int); +int execl(const char *, const char *, ...); +int execle(const char *, const char *, ...); +int execlp(const char *, const char *, ...); +int execv(const char *, char * const *); +int execve(const char *, char * const *, char * const *); +int execvp(const char *, char * const *); +pid_t fork(void); +long fpathconf(int, int); +char *getcwd(char *, size_t); +int getdomainname(char *, int); +gid_t getegid(void); +uid_t geteuid(void); +gid_t getgid(void); +int getgroups(int, gid_t []); +char *getlogin(void); +int getlogin_r(char *, int); +pid_t getpgrp(void); +pid_t getpid(void); +pid_t getppid(void); +uid_t getuid(void); +int isatty(int); +int link(const char *, const char *); +off_t lseek(int, off_t, int); +long pathconf(const char *, int); +int pause(void); +int pipe(int *); +ssize_t read(int, void *, size_t); +int rmdir(const char *); +int setdomainname(const char *, int); +int setgid(gid_t); +int setpgid(pid_t, pid_t); +pid_t setsid(void); +int setuid(uid_t); +unsigned int sleep(unsigned int); +long sysconf(int); +pid_t tcgetpgrp(int); +int tcsetpgrp(int, pid_t); +char *ttyname(int); +char *ttyname_r(int, char *, size_t); +int unlink(const char *); +ssize_t write(int, const void *, size_t); extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt, optreset; -int getopt __P((int, char * const [], const char *)); +int getopt(int, char * const [], const char *); #ifndef _POSIX_SOURCE #ifdef __STDC__ +struct timespec; /* pselect(3) */ struct timeval; /* select(2) */ #endif -int acct __P((const char *)); -int async_daemon __P((void)); -char *brk __P((const char *)); -int chroot __P((const char *)); -char *crypt __P((const char *, const char *)); -int des_cipher __P((const char *, char *, long, int)); -int des_setkey __P((const char *key)); -int encrypt __P((char *, int)); -void endusershell __P((void)); -int exect __P((const char *, char * const *, char * const *)); -int fchdir __P((int)); -int fchown __P((int, int, int)); -char *fflagstostr __P((u_long)); -int fsync __P((int)); -int ftruncate __P((int, off_t)); -int getdtablesize __P((void)); -int getgrouplist __P((const char *, int, int *, int *)); -long gethostid __P((void)); -int gethostname __P((char *, int)); -mode_t getmode __P((const void *, mode_t)); -__pure int - getpagesize __P((void)); -char *getpass __P((const char *)); -int getpgid __P((pid_t _pid)); -int getsid __P((pid_t _pid)); -char *getusershell __P((void)); -char *getwd __P((char *)); /* obsoleted by getcwd() */ -int initgroups __P((const char *, int)); -int iruserok __P((unsigned long, int, const char *, const char *)); -int issetugid __P((void)); -char *mkdtemp __P((char *)); -int mknod __P((const char *, mode_t, dev_t)); -int mkstemp __P((char *)); -int mkstemps __P((char *, int)); -char *mktemp __P((char *)); -int nfssvc __P((int, void *)); -int nice __P((int)); -ssize_t pread __P((int, void *, size_t, off_t)); +int acct(const char *); +int async_daemon(void); +char *brk(const char *); +int chroot(const char *); +char *crypt(const char *, const char *); +int des_cipher(const char *, char *, long, int); +int des_setkey(const char *key); +int encrypt(char *, int); +void endusershell(void); +int fchdir(int); +int fchown(int, int, int); +char *fflagstostr(u_long); +int fsync(int); +int ftruncate(int, off_t); +int getdtablesize(void); +int getgrouplist(const char *, int, int *, int *); +long gethostid(void); +int gethostname(char *, int); +mode_t getmode(const void *, mode_t); +int getpagesize(void) __pure2; +char *getpass(const char *); +int getpgid(pid_t _pid); +int getsid(pid_t _pid); +char *getusershell(void); +char *getwd(char *); /* obsoleted by getcwd() */ +int lockf(int, int, off_t); +int initgroups(const char *, int); +int iruserok(unsigned long, int, const char *, const char *); +int issetugid(void); +char *mkdtemp(char *); +int mknod(const char *, mode_t, dev_t); +int mkstemp(char *); +int mkstemps(char *, int); +char *mktemp(char *); +int nfssvc(int, void *); +int nice(int); +ssize_t pread(int, void *, size_t, off_t); #if 0 -void psignal __P((unsigned int, const char *)); +void psignal(unsigned int, const char *); extern __const char *__const sys_siglist[]; #else #include #endif -int profil __P((char *, int, int, int)); -ssize_t pwrite __P((int, const void *, size_t, off_t)); -int rcmd __P((char **, int, const char *, - const char *, const char *, int *)); -char *re_comp __P((const char *)); -int re_exec __P((const char *)); -int readlink __P((const char *, char *, int)); -int reboot __P((int)); -int revoke __P((const char *)); -int rresvport __P((int *)); -int ruserok __P((const char *, int, const char *, const char *)); -char *sbrk __P((int)); -int select __P((int, fd_set *, fd_set *, fd_set *, struct timeval *)); -int setegid __P((gid_t)); -int seteuid __P((uid_t)); -int setgroups __P((int, const gid_t *)); -void sethostid __P((long)); -int sethostname __P((const char *, int)); -int setkey __P((const char *)); -int setlogin __P((const char *)); -void *setmode __P((const char *)); -int setpgrp __P((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */ -int setregid __P((gid_t, gid_t)); -int setreuid __P((uid_t, uid_t)); -int setrgid __P((gid_t)); -int setruid __P((uid_t)); -void setusershell __P((void)); -int strtofflags __P((char **, u_long *, u_long *)); -int swapon __P((const char *)); -int symlink __P((const char *, const char *)); -void sync __P((void)); -int syscall __P((int, ...)); -int truncate __P((const char *, off_t)); -int ttyslot __P((void)); -unsigned int ualarm __P((unsigned int, unsigned int)); -int unwhiteout __P((const char *)); -int usleep __P((unsigned int)); -void *valloc __P((size_t)); -pid_t vfork __P((void)); +int profil(char *, int, int, int); +#ifndef __MWERKS__ +int pselect(int, fd_set *, fd_set *, fd_set *, + const struct timespec *, const sigset_t *); +#endif /* ! __MWERKS__ */ +ssize_t pwrite(int, const void *, size_t, off_t); +int rcmd(char **, int, const char *, const char *, const char *, int *); +int readlink(const char *, char *, int); +int reboot(int); +int revoke(const char *); +int rresvport(int *); +int rresvport_af(int *, int); +int ruserok(const char *, int, const char *, const char *); +char *sbrk(int); +int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +int setegid(gid_t); +int seteuid(uid_t); +int setgroups(int, const gid_t *); +void sethostid(long); +int sethostname(const char *, int); +int setkey(const char *); +int setlogin(const char *); +void *setmode(const char *); +int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */ +int setregid(gid_t, gid_t); +int setreuid(uid_t, uid_t); +int setrgid(gid_t); +int setruid(uid_t); +void setusershell(void); +int strtofflags(char **, u_long *, u_long *); +int swapon(const char *); +int symlink(const char *, const char *); +void sync(void); +int syscall(int, ...); +int truncate(const char *, off_t); +int ttyslot(void); +unsigned int ualarm(unsigned int, unsigned int); +int undelete(const char *); +int unwhiteout(const char *); +int usleep(unsigned int); +void *valloc(size_t); +pid_t vfork(void); extern char *suboptarg; /* getsubopt(3) external variable */ -int getsubopt __P((char **, char * const *, char **)); +int getsubopt(char **, char * const *, char **); /* HFS & HFS Plus semantics system calls go here */ -int getattrlist __P((const char*,void*,void*,size_t,unsigned long)); -int setattrlist __P((const char*,void*,void*,size_t,unsigned long)); -int exchangedata __P((const char*,const char*,unsigned long)); -int checkuseraccess __P((const char*,uid_t,gid_t*,int,int,unsigned long)); -int getdirentriesattr __P((int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long)); -int searchfs __P((const char*,void*,void*,unsigned long,unsigned long,void*)); - -int fsctl __P((const char *,unsigned long,void*,unsigned long)); +int getattrlist(const char*,void*,void*,size_t,unsigned long); +int setattrlist(const char*,void*,void*,size_t,unsigned long); +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*); + +int fsctl(const char *,unsigned long,void*,unsigned long); #endif /* !_POSIX_SOURCE */ diff --git a/include/util.h b/include/util.h index f2fd6e2..1da5789 100644 --- a/include/util.h +++ b/include/util.h @@ -71,40 +71,37 @@ #define PIDLOCK_NONBLOCK 1 #define PIDLOCK_USEHOSTNAME 2 +/* + * fparseln() specific operation flags. + */ #define FPARSELN_UNESCESC 0x01 #define FPARSELN_UNESCCONT 0x02 #define FPARSELN_UNESCCOMM 0x04 #define FPARSELN_UNESCREST 0x08 #define FPARSELN_UNESCALL 0x0f +/* + * opendev() specific operation flags. + */ +#define OPENDEV_PART 0x01 /* Try to open the raw partition. */ +#define OPENDEV_BLCK 0x04 /* Open block, not character device. */ + __BEGIN_DECLS -void login __P((struct utmp *)); -int login_tty __P((int)); -int logout __P((const char *)); -void logwtmp __P((const char *, const char *, const char *)); -int pw_lock __P((int retries)); -int pw_mkdb __P((void)); -int pw_abort __P((void)); -void pw_init __P((void)); -void pw_edit __P((int notsetuid, const char *filename)); -void pw_prompt __P((void)); -void pw_copy __P((int ffd, int tfd, struct passwd *pw, - struct passwd *old_pw)); -int pw_scan __P((char *bp, struct passwd *pw, int *flags)); -void pw_error __P((const char *name, int err, int eval)); -int openpty __P((int *, int *, char *, struct termios *, - struct winsize *)); -char *fparseln __P((FILE *, size_t *, size_t *, const char[3], int)); -pid_t forkpty __P((int *, char *, struct termios *, struct winsize *)); -int getmaxpartitions __P((void)); -int getrawpartition __P((void)); -int opendisk __P((const char *, int, char *, size_t, int)); -int pidlock __P((const char *, int, pid_t *, const char *)); -int ttylock __P((const char *, int, pid_t *)); -int ttyunlock __P((const char *)); -int ttyaction __P((char *tty, char *act, char *user)); +void login(struct utmp *); +int login_tty(int); +int logout(const char *); +void logwtmp(const char *, const char *, const char *); +int opendev(char *, int, int, char **); +int openpty(int *, int *, char *, struct termios *, + struct winsize *); +char *fparseln(FILE *, size_t *, size_t *, const char[3], int); +pid_t forkpty(int *, char *, struct termios *, struct winsize *); +int pidlock(const char *, int, pid_t *, const char *); +int ttylock(const char *, int, pid_t *); +int ttyunlock(const char *); +int ttyaction(char *tty, char *act, char *user); struct iovec; -char *ttymsg __P((struct iovec *, int, const char *, int)); +char *ttymsg(struct iovec *, int, const char *, int); __END_DECLS #endif /* !_UTIL_H_ */ diff --git a/include/utime.h b/include/utime.h index cbed7f0..c2121ca 100644 --- a/include/utime.h +++ b/include/utime.h @@ -68,7 +68,7 @@ struct utimbuf { #include __BEGIN_DECLS -int utime __P((const char *, const struct utimbuf *)); +int utime(const char *, const struct utimbuf *); __END_DECLS #endif /* !_UTIME_H_ */ diff --git a/include/vis.h b/include/vis.h index 55c0139..3b3519d 100644 --- a/include/vis.h +++ b/include/vis.h @@ -80,6 +80,7 @@ * other */ #define VIS_NOSLASH 0x40 /* inhibit printing '\' */ +#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ /* * unvis return codes @@ -98,11 +99,12 @@ #include __BEGIN_DECLS -char *vis __P((char *, int, int, int)); -int strvis __P((char *, const char *, int)); -int strvisx __P((char *, const char *, size_t, int)); -int strunvis __P((char *, const char *)); -int unvis __P((char *, int, int *, int)); +char *vis(char *, int, int, int); +int strvis(char *, const char *, int); +int strvisx(char *, const char *, size_t, int); +int strunvis(char *, const char *); +int strunvisx(char *, const char *, int); +int unvis(char *, int, int *, int); __END_DECLS #endif /* !_VIS_H_ */ diff --git a/include/wchar.h b/include/wchar.h new file mode 100644 index 0000000..40d2112 --- /dev/null +++ b/include/wchar.h @@ -0,0 +1,216 @@ +/*- + * 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. + * + * $FreeBSD: /repoman/r/ncvs/src/include/wchar.h,v 1.34 2003/03/13 06:29:53 tjr Exp $ + */ + +/*- + * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Julian Coleman. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the 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: wchar.h,v 1.8 2000/12/22 05:31:42 itojun Exp $ + */ + +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + +#include +#include +#include + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef _BSD_SIZE_T_DEFINED_ +#define _BSD_SIZE_T_DEFINED_ +typedef _BSD_SIZE_T_ size_t; +#endif + +#ifndef _BSD_MBSTATE_T_DEFINED_ +#define _BSD_MBSTATE_T_DEFINED_ +typedef _BSD_MBSTATE_T_ mbstate_t; +#endif + +#ifndef _BSD_CT_RUNE_T_DEFINED_ +#define _BSD_CT_RUNE_T_DEFINED_ +typedef _BSD_CT_RUNE_T_ ct_rune_t; +#endif + +#ifndef _BSD_RUNE_T_DEFINED_ +#define _BSD_RUNE_T_DEFINED_ +typedef _BSD_RUNE_T_ rune_t; +#endif + +#ifndef __cplusplus +#ifndef _BSD_WCHAR_T_DEFINED_ +#define _BSD_WCHAR_T_DEFINED_ +#ifdef __WCHAR_TYPE__ +typedef __WCHAR_TYPE__ wchar_t; +#else /* ! __WCHAR_TYPE__ */ +typedef _BSD_WCHAR_T_ wchar_t; +#endif /* __WCHAR_TYPE__ */ +#endif /* _BSD_WCHAR_T_DEFINED_ */ +#endif /* __cplusplus */ + +#ifndef _BSD_WINT_T_DEFINED_ +#define _BSD_WINT_T_DEFINED_ +typedef _BSD_WINT_T_ wint_t; +#endif + +#ifndef WEOF +#define WEOF ((wint_t)-1) +#endif + +#ifndef WCHAR_MIN +#define WCHAR_MIN 0 +#endif + +#ifndef WCHAR_MAX +#ifdef __WCHAR_MAX__ +#define WCHAR_MAX __WCHAR_MAX__ +#else /* ! __WCHAR_MAX__ */ +#define WCHAR_MAX 0x7fffffff +#endif /* __WCHAR_MAX__ */ +#endif + +struct __sFILE; +struct tm; + +__BEGIN_DECLS +wint_t btowc(int); +wint_t fgetwc(struct __sFILE *); +wchar_t *fgetws(wchar_t * __restrict, int, struct __sFILE * __restrict); +wint_t fputwc(wchar_t, struct __sFILE *); +int fputws(const wchar_t * __restrict, struct __sFILE * __restrict); +int fwide(struct __sFILE *, int); +int fwprintf(struct __sFILE * __restrict, const wchar_t * __restrict, ...); +int fwscanf(struct __sFILE * __restrict, const wchar_t * __restrict, ...); +wint_t getwc(struct __sFILE *); +wint_t getwchar(void); +size_t mbrlen(const char * __restrict, size_t, mbstate_t * __restrict); +size_t mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict); +int mbsinit(const mbstate_t *); +size_t mbsrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, + mbstate_t * __restrict); +wint_t putwc(wchar_t, struct __sFILE *); +wint_t putwchar(wchar_t); +int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict, + ...); +int swscanf(const wchar_t * __restrict, const wchar_t * __restrict, ...); +wint_t ungetwc(wint_t, struct __sFILE *); +int vfwprintf(struct __sFILE * __restrict, const wchar_t * __restrict, + _BSD_VA_LIST_); +int vswprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict, + _BSD_VA_LIST_); +int vwprintf(const wchar_t * __restrict, _BSD_VA_LIST_); +size_t wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); +wchar_t *wcscat(wchar_t * __restrict, const wchar_t * __restrict); +wchar_t *wcschr(const wchar_t *, wchar_t); +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 *); +size_t wcsftime(wchar_t * __restrict, size_t, const wchar_t * __restrict, + const struct tm * __restrict); +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); +wchar_t *wcsncpy(wchar_t * __restrict , const wchar_t * __restrict, size_t); +wchar_t *wcspbrk(const wchar_t *, const wchar_t *); +wchar_t *wcsrchr(const wchar_t *, wchar_t); +size_t wcsrtombs(char * __restrict, const wchar_t ** __restrict, size_t, + mbstate_t * __restrict); +size_t wcsspn(const wchar_t *, const wchar_t *); +wchar_t *wcsstr(const wchar_t * __restrict, const wchar_t * __restrict); +size_t wcsxfrm(wchar_t * __restrict, const wchar_t * __restrict, size_t); +int wctob(wint_t); +double wcstod(const wchar_t * __restrict, wchar_t ** __restrict); +wchar_t *wcstok(wchar_t * __restrict, const wchar_t * __restrict, + wchar_t ** __restrict); +long wcstol(const wchar_t * __restrict, wchar_t ** __restrict, int); +unsigned long + wcstoul(const wchar_t * __restrict, wchar_t ** __restrict, int); +wchar_t *wmemchr(const wchar_t *, wchar_t, size_t); +int wmemcmp(const wchar_t *, const wchar_t *, size_t); +wchar_t *wmemcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); +wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); +wchar_t *wmemset(wchar_t *, wchar_t, size_t); +int wprintf(const wchar_t * __restrict, ...); +int wscanf(const wchar_t * __restrict, ...); + +#if !defined(_ANSI_SOURCE) +int vfwscanf(struct __sFILE * __restrict, const wchar_t * __restrict, + _BSD_VA_LIST_); +int vswscanf(const wchar_t * __restrict, const wchar_t * __restrict, + _BSD_VA_LIST_); +int vwscanf(const wchar_t * __restrict, _BSD_VA_LIST_); +float wcstof(const wchar_t * __restrict, wchar_t ** __restrict); +long double + wcstold(const wchar_t * __restrict, wchar_t ** __restrict); +long long + wcstoll(const wchar_t * __restrict, wchar_t ** __restrict, int); +unsigned long long + wcstoull(const wchar_t * __restrict, wchar_t ** __restrict, int); +int wcswidth(const wchar_t *, size_t); +int wcwidth(wchar_t); +size_t wcslcat(wchar_t *, const wchar_t *, size_t); +size_t wcslcpy(wchar_t *, const wchar_t *, size_t); +#endif /* !defined(_ANSI_SOURCE) */ +__END_DECLS + +#endif /* !_WCHAR_H_ */ diff --git a/include/wctype.h b/include/wctype.h new file mode 100644 index 0000000..eb42efe --- /dev/null +++ b/include/wctype.h @@ -0,0 +1,138 @@ +/*- + * 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: wctype.h,v 1.4 2000/12/21 01:50:21 itojun Exp + * $NetBSD: wctype.h,v 1.3 2000/12/22 14:16:16 itojun Exp $ + * $FreeBSD: /repoman/r/ncvs/src/include/wctype.h,v 1.10 2002/08/21 16:19:55 mike Exp $ + */ + +#ifndef _WCTYPE_H_ +#define _WCTYPE_H_ + +#include +#include + +#include + +#ifndef _BSD_CT_RUNE_T_DEFINED_ +#define _BSD_CT_RUNE_T_DEFINED_ +typedef _BSD_CT_RUNE_T_ ct_rune_t; +#endif + +#ifndef _BSD_RUNE_T_DEFINED_ +#define _BSD_RUNE_T_DEFINED_ +typedef _BSD_RUNE_T_ rune_t; +#endif + +#ifndef __cplusplus +#ifndef _BSD_WCHAR_T_DEFINED_ +#define _BSD_WCHAR_T_DEFINED_ +#ifdef __WCHAR_TYPE__ +typedef __WCHAR_TYPE__ wchar_t; +#else /* ! __WCHAR_TYPE__ */ +typedef _BSD_WCHAR_T_ wchar_t; +#endif /* __WCHAR_TYPE__ */ +#endif /* _BSD_WCHAR_T_DEFINED_ */ +#endif /* __cplusplus */ + +#ifndef _BSD_WINT_T_DEFINED_ +#define _BSD_WINT_T_DEFINED_ +typedef _BSD_WINT_T_ wint_t; +#endif + +#ifndef _WCTRANS_T +typedef int wctrans_t; +#define _WCTRANS_T +#endif + +#ifndef _WCTYPE_T +typedef unsigned long wctype_t; +#define _WCTYPE_T +#endif + +#ifndef WEOF +#define WEOF ((wint_t)-1) +#endif + +__BEGIN_DECLS +int iswalnum(wint_t); +int iswalpha(wint_t); +int iswblank(wint_t); +int iswcntrl(wint_t); +int iswctype(wint_t, wctype_t); +int iswdigit(wint_t); +int iswgraph(wint_t); +int iswlower(wint_t); +int iswprint(wint_t); +int iswpunct(wint_t); +int iswspace(wint_t); +int iswupper(wint_t); +int iswxdigit(wint_t); +wint_t towctrans(wint_t, wctrans_t); +wint_t towlower(wint_t); +wint_t towupper(wint_t); +wctrans_t + wctrans(const char *); +wctype_t + wctype(const char *); + +#if !defined(_ANSI_SOURCE) +wint_t iswascii(wint_t); +wint_t iswhexnumber(wint_t); +wint_t iswideogram(wint_t); +wint_t iswnumber(wint_t); +wint_t iswphonogram(wint_t); +wint_t iswrune(wint_t); +wint_t iswspecial(wint_t); +#endif +__END_DECLS + +#define iswalnum(wc) __istype((wc), _CTYPE_A|_CTYPE_D) +#define iswalpha(wc) __istype((wc), _CTYPE_A) +#define iswblank(wc) __istype((wc), _CTYPE_B) +#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) + +#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) +#endif + +#endif /* _WCTYPE_H_ */ diff --git a/internat/Makefile.inc b/internat/Makefile.inc index 2f3fdcc..d3d5003 100644 --- a/internat/Makefile.inc +++ b/internat/Makefile.inc @@ -3,4 +3,4 @@ SRCS += NXCType.c NXIsCntrl.c NXIsPrint.c NXIsXDigit.c _NXToLower.c \ NXIsAlNum.c NXIsDigit.c NXIsPunct.c NXToAscii.c _NXToUpper.c \ NXIsAlpha.c NXIsGraph.c NXIsSpace.c NXToLower.c \ - NXIsAscii.c NXIsLower.c NXIsUpper.c NXToUpper.c \ + NXIsAscii.c NXIsLower.c NXIsUpper.c NXToUpper.c diff --git a/internat/NXIsAscii.c b/internat/NXIsAscii.c index 7003124..5acc0cb 100644 --- a/internat/NXIsAscii.c +++ b/internat/NXIsAscii.c @@ -29,6 +29,7 @@ #include "NXCType.h" #define FIXSIGNEDCHAR(i) if ((i & 0xFFFFFF80) == 0xFFFFFF80) i &= 0x000000FF +int NXIsAscii(c) unsigned int c; { diff --git a/internat/NXToLower.c b/internat/NXToLower.c index aa6b7b7..b66859f 100644 --- a/internat/NXToLower.c +++ b/internat/NXToLower.c @@ -29,6 +29,7 @@ #include "NXCType.h" #define FIXSIGNEDCHAR(i) if ((i & 0xFFFFFF80) == 0xFFFFFF80) i &= 0x000000FF +int NXToLower(c) unsigned int c; { diff --git a/internat/NXToUpper.c b/internat/NXToUpper.c index e552cb4..e57b11e 100644 --- a/internat/NXToUpper.c +++ b/internat/NXToUpper.c @@ -29,6 +29,7 @@ #include "NXCType.h" #define FIXSIGNEDCHAR(i) if ((i & 0xFFFFFF80) == 0xFFFFFF80) i &= 0x000000FF +int NXToUpper(c) unsigned int c; { diff --git a/internat/_NXToLower.c b/internat/_NXToLower.c index f6ec1b9..2f91ce2 100644 --- a/internat/_NXToLower.c +++ b/internat/_NXToLower.c @@ -29,6 +29,7 @@ #include "NXCType.h" #define FIXSIGNEDCHAR(i) if ((i & 0xFFFFFF80) == 0xFFFFFF80) i &= 0x000000FF +int _NXToLower(c) unsigned int c; { diff --git a/internat/_NXToUpper.c b/internat/_NXToUpper.c index 823115d..6fe17e2 100644 --- a/internat/_NXToUpper.c +++ b/internat/_NXToUpper.c @@ -29,6 +29,7 @@ #include "NXCType.h" #define FIXSIGNEDCHAR(i) if ((i & 0xFFFFFF80) == 0xFFFFFF80) i &= 0x000000FF +int _NXToUpper(c) unsigned int c; { diff --git a/locale/big5.c b/locale/FreeBSD/big5.c similarity index 93% rename from locale/big5.c rename to locale/FreeBSD/big5.c index 87e2fd8..4bc3cbd 100644 --- a/locale/big5.c +++ b/locale/FreeBSD/big5.c @@ -32,13 +32,13 @@ * LIABILITY, OR TORT (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/big5.c,v 1.3.2.2 2001/03/05 10:02:54 obrien Exp $ */ #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.7 2002/03/22 21:52:18 obrien Exp $"); #include #include @@ -46,8 +46,8 @@ static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93"; #include #include -rune_t _BIG5_sgetrune __P((const char *, size_t, char const **)); -int _BIG5_sputrune __P((rune_t, char *, size_t, char **)); +rune_t _BIG5_sgetrune(const char *, size_t, char const **); +int _BIG5_sputrune(rune_t, char *, size_t, char **); int _BIG5_init(rl) diff --git a/locale/FreeBSD/big5.c.patch b/locale/FreeBSD/big5.c.patch new file mode 100644 index 0000000..4b5f47d --- /dev/null +++ b/locale/FreeBSD/big5.c.patch @@ -0,0 +1,32 @@ +--- big5.c.orig Tue May 20 15:21:44 2003 ++++ big5.c Wed Jun 18 12:02:34 2003 +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + rune_t _BIG5_sgetrune(const char *, size_t, char const **); + int _BIG5_sputrune(rune_t, char *, size_t, char **); +@@ -77,13 +78,17 @@ + rune_t rune = 0; + int len; + +- if (n < 1 || (len = _big5_check(*string)) > n) { +- if (result) +- *result = string; ++ if (result) ++ *result = string; ++ if (n < 1 || (len = _big5_check(*string)) > n) + return (_INVALID_RUNE); +- } + while (--len >= 0) + rune = (rune << 8) | ((u_int)(*string++) & 0xff); ++ if (!isrune(rune)) { ++ if (result) ++ (*result)++; ++ return (_INVALID_RUNE); ++ } + if (result) + *result = string; + return rune; diff --git a/locale/FreeBSD/btowc.3 b/locale/FreeBSD/btowc.3 new file mode 100644 index 0000000..da9d1e5 --- /dev/null +++ b/locale/FreeBSD/btowc.3 @@ -0,0 +1,79 @@ +.\" 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 wctob +.Nd "convert between wide and single-byte characters" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft wint_t +.Fn btowc "int c" +.Ft int +.Fn wctob "wint_t c" +.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 . +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr multibyte 3 , +.Xr wcrtomb 3 +.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/FreeBSD/btowc.c b/locale/FreeBSD/btowc.c new file mode 100644 index 0000000..4b5964b --- /dev/null +++ b/locale/FreeBSD/btowc.c @@ -0,0 +1,45 @@ +/*- + * 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/btowc.c,v 1.1 2002/08/03 13:49:55 tjr Exp $"); + +#include +#include + +wint_t +btowc(int c) +{ + rune_t r; + char cc; + + if (c == EOF) + return (WEOF); + cc = (char)c; + if ((r = sgetrune(&cc, 1, NULL)) == _INVALID_RUNE) + return (WEOF); + return (r); +} diff --git a/locale/FreeBSD/collate.c b/locale/FreeBSD/collate.c new file mode 100644 index 0000000..abc5f24 --- /dev/null +++ b/locale/FreeBSD/collate.c @@ -0,0 +1,291 @@ +/*- + * 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.32 2002/10/29 09:03:57 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "collate.h" +#include "setlocale.h" +#include "ldpart.h" + +#include "libc_private.h" + +int __collate_load_error = 1; +int __collate_substitute_nontrivial; + +u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; +struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; +struct __collate_st_chain_pri *__collate_chain_pri_table; + +void __collate_err(int ex, const char *f) __dead2; + +int +__collate_load_tables(const char *encoding) +{ + FILE *fp; + int i, saverr, chains; + uint32_t u32; + 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]; + + /* 'encoding' must be already checked. */ + if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { + __collate_load_error = 1; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (strcmp(encoding, collate_encoding) == 0) { + __collate_load_error = 0; + 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_VERSION) == 0) + chains = 0; + else if (strcmp(strbuf, COLLATE_VERSION1_1) == 0) + chains = 1; + if (chains < 0) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); + } + if (chains) { + if (fread(&u32, sizeof(u32), 1, fp) != 1) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + if ((chains = (int)ntohl(u32)) < 1) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); + } + } else + chains = TABLE_SIZE; + + if ((TMP_substitute_table = + malloc(sizeof(__collate_substitute_table))) == NULL) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + if ((TMP_char_pri_table = + malloc(sizeof(__collate_char_pri_table))) == NULL) { + saverr = errno; + free(TMP_substitute_table); + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + if ((TMP_chain_pri_table = + malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) { + saverr = errno; + free(TMP_substitute_table); + free(TMP_char_pri_table); + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + +#define FREAD(a, b, c, d) \ +{ \ + if (fread(a, b, c, d) != c) { \ + saverr = errno; \ + free(TMP_substitute_table); \ + free(TMP_char_pri_table); \ + free(TMP_chain_pri_table); \ + (void)fclose(d); \ + errno = saverr; \ + return (_LDP_ERROR); \ + } \ +} + + FREAD(TMP_substitute_table, sizeof(__collate_substitute_table), 1, fp); + FREAD(TMP_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); + FREAD(TMP_chain_pri_table, + sizeof(*__collate_chain_pri_table), chains, fp); + (void)fclose(fp); + + (void)strcpy(collate_encoding, encoding); + if (__collate_substitute_table_ptr != NULL) + free(__collate_substitute_table_ptr); + __collate_substitute_table_ptr = TMP_substitute_table; + if (__collate_char_pri_table_ptr != NULL) + free(__collate_char_pri_table_ptr); + __collate_char_pri_table_ptr = TMP_char_pri_table; + 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; + } + } + __collate_load_error = 0; + + return (_LDP_LOADED); +} + +u_char * +__collate_substitute(s) + const u_char *s; +{ + int dest_len, len, nlen; + int delta = strlen(s); + u_char *dest_str = NULL; + + if (s == NULL || *s == '\0') + return (__collate_strdup("")); + delta += delta / 8; + dest_str = malloc(dest_len = delta); + if (dest_str == NULL) + __collate_err(EX_OSERR, __FUNCTION__); + len = 0; + while (*s) { + nlen = len + strlen(__collate_substitute_table[*s]); + if (dest_len <= nlen) { + dest_str = reallocf(dest_str, dest_len = nlen + delta); + if (dest_str == NULL) + __collate_err(EX_OSERR, __FUNCTION__); + } + (void)strcpy(dest_str + len, __collate_substitute_table[*s++]); + len = nlen; + } + return (dest_str); +} + +void +__collate_lookup(t, len, prim, sec) + const u_char *t; + int *len, *prim, *sec; +{ + struct __collate_st_chain_pri *p2; + + *len = 1; + *prim = *sec = 0; + for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) { + if (*t == p2->str[0] && + strncmp(t, p2->str, strlen(p2->str)) == 0) { + *len = strlen(p2->str); + *prim = p2->prim; + *sec = p2->sec; + return; + } + } + *prim = __collate_char_pri_table[*t].prim; + *sec = __collate_char_pri_table[*t].sec; +} + +u_char * +__collate_strdup(s) + u_char *s; +{ + u_char *t = strdup(s); + + if (t == NULL) + __collate_err(EX_OSERR, __FUNCTION__); + return (t); +} + +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); +} + +#ifdef COLLATE_DEBUG +void +__collate_print_tables() +{ + int i; + struct __collate_st_chain_pri *p2; + + 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++) + printf("\t\"%s\" : %d %d\n", p2->str, p2->prim, p2->sec); + printf("Char priority table:\n"); + 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); +} +#endif diff --git a/locale/FreeBSD/collate.c.patch b/locale/FreeBSD/collate.c.patch new file mode 100644 index 0000000..3e6e844 --- /dev/null +++ b/locale/FreeBSD/collate.c.patch @@ -0,0 +1,10 @@ +--- collate.c.orig Tue Oct 29 01:03:57 2002 ++++ collate.c Sat May 3 14:14:24 2003 +@@ -29,7 +29,6 @@ + __FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.32 2002/10/29 09:03:57 tjr Exp $"); + + #include "namespace.h" +-#include + #include + #include + #include diff --git a/locale/collate.h b/locale/FreeBSD/collate.h similarity index 74% rename from locale/collate.h rename to locale/FreeBSD/collate.h index 97d9c5b..4d55f9c 100644 --- a/locale/collate.h +++ b/locale/FreeBSD/collate.h @@ -24,11 +24,11 @@ * 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.9 1999/09/12 21:15:14 dt Exp $ + * $FreeBSD: src/lib/libc/locale/collate.h,v 1.14 2002/08/30 20:26:02 ache Exp $ */ -#ifndef COLLATE_H_INCLUDED -#define COLLATE_H_INCLUDED +#ifndef _COLLATE_H_ +#define _COLLATE_H_ #include #include @@ -36,7 +36,8 @@ #define STR_LEN 10 #define TABLE_SIZE 100 -#define COLLATE_VERSION "1.0\n" +#define COLLATE_VERSION "1.0\n" +#define COLLATE_VERSION1_1 "1.1\n" struct __collate_st_char_pri { int prim, sec; @@ -48,20 +49,21 @@ struct __collate_st_chain_pri { extern int __collate_load_error; extern int __collate_substitute_nontrivial; -extern char __collate_version[STR_LEN]; +#define __collate_substitute_table (*__collate_substitute_table_ptr) extern u_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[TABLE_SIZE]; +extern struct __collate_st_chain_pri *__collate_chain_pri_table; __BEGIN_DECLS -u_char *__collate_strdup __P((u_char *)); -u_char *__collate_substitute __P((const u_char *)); -int __collate_load_tables __P((char *)); -void __collate_lookup __P((const u_char *, int *, int *, int *)); -int __collate_range_cmp __P((int, int)); +u_char *__collate_strdup(u_char *); +u_char *__collate_substitute(const u_char *); +int __collate_load_tables(const char *); +void __collate_lookup(const u_char *, int *, int *, int *); +int __collate_range_cmp(int, int); #ifdef COLLATE_DEBUG -void __collate_print_tables __P((void)); +void __collate_print_tables(void); #endif __END_DECLS -#endif /* not COLLATE_H_INCLUDED */ +#endif /* !_COLLATE_H_ */ diff --git a/locale/collcmp.c b/locale/FreeBSD/collcmp.c similarity index 95% rename from locale/collcmp.c rename to locale/FreeBSD/collcmp.c index b1e8e0a..97046a9 100644 --- a/locale/collcmp.c +++ b/locale/FreeBSD/collcmp.c @@ -22,10 +22,11 @@ * LIABILITY, OR TORT (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/collcmp.c,v 1.12.2.1 2000/08/22 01:54:39 jhb Exp $ */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.14 2002/03/22 21:52:18 obrien Exp $"); + #define ASCII_COMPATIBLE_COLLATE /* see share/colldef */ #include diff --git a/locale/ctype.3 b/locale/FreeBSD/ctype.3 similarity index 96% rename from locale/ctype.3 rename to locale/FreeBSD/ctype.3 index f946e12..0275a9a 100644 --- a/locale/ctype.3 +++ b/locale/FreeBSD/ctype.3 @@ -30,12 +30,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctype.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/ctype.3,v 1.6.2.3 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/ctype.3,v 1.12 2002/12/18 13:33:03 ru Exp $ .\" .Dd June 4, 1993 .Dt CTYPE 3 .Os .Sh NAME +.Nm digittoint , .Nm isalnum , .Nm isalpha , .Nm isascii , @@ -64,6 +65,8 @@ .Sh SYNOPSIS .In ctype.h .Ft int +.Fn digittoint "int c" +.Ft int .Fn isalnum "int c" .Ft int .Fn isalpha "int c" @@ -107,12 +110,13 @@ .Fn toupper "int c" .Sh DESCRIPTION The above functions perform character tests and conversions on the integer -.Ar c . +.Fa c . They are available as macros, defined in the include file .Aq Pa ctype.h , or as true functions in the C library. See the specific manual pages for more information. .Sh SEE ALSO +.Xr digittoint 3 , .Xr isalnum 3 , .Xr isalpha 3 , .Xr isascii 3 , @@ -134,7 +138,6 @@ See the specific manual pages for more information. These functions, except for .Fn digittoint , .Fn isascii , -.Fn isblank , .Fn ishexnumber , .Fn isideogram , .Fn isnumber , diff --git a/gen/getbootfile.3 b/locale/FreeBSD/digittoint.3 similarity index 66% rename from gen/getbootfile.3 rename to locale/FreeBSD/digittoint.3 index 55cb6fe..98e8598 100644 --- a/gen/getbootfile.3 +++ b/locale/FreeBSD/digittoint.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1983, 1991, 1993 +.\" Copyright (c) 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -29,44 +29,48 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" From: @(#)gethostname.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getbootfile.3,v 1.9 2001/10/01 16:08:50 ru Exp $ +.\" @(#)digittoint.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/locale/digittoint.3,v 1.2 2002/03/18 15:44:27 ru Exp $ .\" -.Dd September 23, 1994 -.Dt GETBOOTFILE 3 +.Dd April 6, 2001 +.Dt DIGITTOINT 3 .Os .Sh NAME -.Nm getbootfile -.Nd get kernel boot file name +.Nm digittoint +.Nd convert a numeric character to its integer value .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In paths.h -.Ft const char * -.Fn getbootfile void +.In ctype.h +.Ft int +.Fn digittoint "int c" .Sh DESCRIPTION The -.Fn getbootfile -function retrieves the full pathname of the file from which the -current kernel was loaded, and returns a static pointer to the name. -A read/write interface to this information is available via the -.Xr sysctl 3 -MIB variable -.Dq Li kern.bootfile . +.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. .Sh RETURN VALUES -If the call succeeds a string giving the pathname is returned. If it -fails, a null pointer is returned and an error code is -placed in the global location -.Va errno . -.Sh SEE ALSO -.Xr sysctl 3 -.Sh BUGS -If the boot blocks have not been modified to pass this information into -the kernel at boot time, the static string -.Dq Pa /kernel -is returned instead of the real boot file. -.Sh HISTORY The -.Fn getbootfile -function call appeared in -.Fx 2.0 . +.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 isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr islower 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isspace 3 , +.Xr isupper 3 , +.Xr isxdigit 3 , +.Xr stdio 3 , +.Xr tolower 3 , +.Xr toupper 3 , +.Xr ascii 7 diff --git a/locale/euc.4 b/locale/FreeBSD/euc.4 similarity index 98% rename from locale/euc.4 rename to locale/FreeBSD/euc.4 index e7c9c92..564358d 100644 --- a/locale/euc.4 +++ b/locale/FreeBSD/euc.4 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)euc.4 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/euc.4,v 1.8.2.1 2001/07/22 12:06:40 dd Exp $ +.\" $FreeBSD: src/lib/libc/locale/euc.4,v 1.9 2001/07/15 07:53:05 dd Exp $ .\" .Dd June 4, 1993 .Dt EUC 4 diff --git a/locale/euc.c b/locale/FreeBSD/euc.c similarity index 85% rename from locale/euc.c rename to locale/FreeBSD/euc.c index 4b7d9eb..02c46ba 100644 --- a/locale/euc.c +++ b/locale/FreeBSD/euc.c @@ -32,13 +32,13 @@ * LIABILITY, OR TORT (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/euc.c,v 1.3.6.1 2000/06/04 21:47:39 ache Exp $ */ #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.11 2002/08/09 08:22:29 ache Exp $"); #include @@ -49,8 +49,8 @@ static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93"; #include #include -rune_t _EUC_sgetrune __P((const char *, size_t, char const **)); -int _EUC_sputrune __P((rune_t, char *, size_t, char **)); +rune_t _EUC_sgetrune(const char *, size_t, char const **); +int _EUC_sputrune(rune_t, char *, size_t, char **); typedef struct { int count[4]; @@ -63,37 +63,36 @@ _EUC_init(rl) _RuneLocale *rl; { _EucInfo *ei; - int x; + int x, new__mb_cur_max; char *v, *e; rl->sgetrune = _EUC_sgetrune; rl->sputrune = _EUC_sputrune; - if (!rl->variable) { - free(rl); + if (rl->variable == NULL) return (EFTYPE); - } - v = (char *) rl->variable; + + v = (char *)rl->variable; while (*v == ' ' || *v == '\t') ++v; - if ((ei = malloc(sizeof(_EucInfo))) == NULL) { - free(rl); - return (ENOMEM); - } + 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); + ei->count[x] = (int)strtol(v, &e, 0); if (v == e || !(v = e)) { - free(rl); 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); + ei->bits[x] = (int)strtol(v, &e, 0); if (v == e || !(v = e)) { - free(rl); free(ei); return (EFTYPE); } @@ -102,19 +101,13 @@ _EUC_init(rl) } ei->mask = (int)strtol(v, &e, 0); if (v == e || !(v = e)) { - free(rl); free(ei); return (EFTYPE); } - if (sizeof(_EucInfo) <= rl->variable_len) { - memcpy(rl->variable, ei, sizeof(_EucInfo)); - free(ei); - } else { - rl->variable = &ei; - } + rl->variable = ei; rl->variable_len = sizeof(_EucInfo); _CurrentRuneLocale = rl; - __mb_cur_max = 3; + __mb_cur_max = new__mb_cur_max; return (0); } @@ -123,6 +116,8 @@ _EUC_init(rl) #define _SS2 0x008e #define _SS3 0x008f +#define GR_BITS 0x80808080 /* XXX: to be fixed */ + static inline int _euc_set(c) u_int c; @@ -202,6 +197,8 @@ CodeSet1: } *string++ = _SS2; --i; + /* SS2 designates G2 into GR */ + nm |= GR_BITS; } else if (m == CEI->bits[3]) { i = len = CEI->count[3]; @@ -212,6 +209,8 @@ CodeSet1: } *string++ = _SS3; --i; + /* SS3 designates G3 into GR */ + nm |= GR_BITS; } else goto CodeSet1; /* Bletch */ while (i-- > 0) diff --git a/locale/FreeBSD/euc.c.patch b/locale/FreeBSD/euc.c.patch new file mode 100644 index 0000000..9d60826 --- /dev/null +++ b/locale/FreeBSD/euc.c.patch @@ -0,0 +1,37 @@ +--- euc.c.orig Tue May 20 15:21:44 2003 ++++ euc.c Wed Jun 18 12:01:30 2003 +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + rune_t _EUC_sgetrune(const char *, size_t, char const **); + int _EUC_sputrune(rune_t, char *, size_t, char **); +@@ -135,11 +136,10 @@ + rune_t rune = 0; + int len, set; + +- if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) { +- if (result) +- *result = string; ++ if (result) ++ *result = string; ++ if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) + return (_INVALID_RUNE); +- } + switch (set) { + case 3: + case 2: +@@ -151,6 +151,11 @@ + while (len-- > 0) + rune = (rune << 8) | ((u_int)(*string++) & 0xff); + break; ++ } ++ if (!isrune(rune)) { ++ if (result) ++ (*result)++; ++ return (_INVALID_RUNE); + } + if (result) + *result = string; diff --git a/locale/FreeBSD/fix_grouping.c b/locale/FreeBSD/fix_grouping.c new file mode 100644 index 0000000..7af4e41 --- /dev/null +++ b/locale/FreeBSD/fix_grouping.c @@ -0,0 +1,83 @@ +/* + * 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.7 2002/03/22 21:52:18 obrien Exp $"); + +#include +#include +#include + +static const char nogrouping[] = { CHAR_MAX, '\0' }; + +/* + * "3;3;-1" -> "\003\003\177" + */ + +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; +} diff --git a/locale/frune.c b/locale/FreeBSD/frune.c similarity index 88% rename from locale/frune.c rename to locale/FreeBSD/frune.c index 443d3ba..54037ce 100644 --- a/locale/frune.c +++ b/locale/FreeBSD/frune.c @@ -37,12 +37,15 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)frune.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/frune.c,v 1.3 2002/09/18 06:19:12 tjr Exp $"); #include #include #include #include +__warn_references(fgetrune, "warning: fgetrune() is deprecated. See fgetrune(3)."); long fgetrune(fp) FILE *fp; @@ -70,6 +73,7 @@ fgetrune(fp) return (_INVALID_RUNE); } +__warn_references(fungetrune, "warning: fungetrune() is deprecated. See fungetrune(3)."); int fungetrune(r, fp) rune_t r; @@ -85,6 +89,7 @@ fungetrune(r, fp) return (0); } +__warn_references(fputrune, "warning: fputrune() is deprecated. See fputrune(3)."); int fputrune(r, fp) rune_t r; diff --git a/locale/isalnum.3 b/locale/FreeBSD/isalnum.3 similarity index 91% rename from locale/isalnum.3 rename to locale/FreeBSD/isalnum.3 index 91d3112..8b998fa 100644 --- a/locale/isalnum.3 +++ b/locale/FreeBSD/isalnum.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalnum.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isalnum.3,v 1.7.2.7 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isalnum.3,v 1.17 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISALNUM 3 .Os .Sh NAME @@ -88,10 +88,22 @@ The .Fn isalnum function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn isalnum +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswalnum +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , .Xr isalpha 3 , .Xr isdigit 3 , +.Xr iswalnum 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isalpha.3 b/locale/FreeBSD/isalpha.3 similarity index 90% rename from locale/isalpha.3 rename to locale/FreeBSD/isalpha.3 index ae00cf4..283348e 100644 --- a/locale/isalpha.3 +++ b/locale/FreeBSD/isalpha.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isalpha.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isalpha.3,v 1.7.2.6 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isalpha.3,v 1.16 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISALPHA 3 .Os .Sh NAME @@ -86,10 +86,22 @@ The .Fn isalpha function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn isalpha +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswalpha +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , .Xr islower 3 , .Xr isupper 3 , +.Xr iswalpha 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isascii.3 b/locale/FreeBSD/isascii.3 similarity index 92% rename from locale/isascii.3 rename to locale/FreeBSD/isascii.3 index 071bb62..b930401 100644 --- a/locale/isascii.3 +++ b/locale/FreeBSD/isascii.3 @@ -30,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isascii.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/locale/isascii.3,v 1.5.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isascii.3,v 1.13 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd December 11, 1993 +.Dd October 6, 2002 .Dt ISASCII 3 .Os .Sh NAME @@ -53,9 +53,5 @@ character, which is any character between 0 and octal 0177 inclusive. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswascii 3 , .Xr ascii 7 -.Sh STANDARDS -The -.Fn isascii -function conforms to -.St -isoC . diff --git a/locale/isblank.3 b/locale/FreeBSD/isblank.3 similarity index 79% rename from locale/isblank.3 rename to locale/FreeBSD/isblank.3 index 82587dc..f0a09f0 100644 --- a/locale/isblank.3 +++ b/locale/FreeBSD/isblank.3 @@ -30,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isblank.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isblank.3,v 1.4.2.3 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isblank.3,v 1.17 2002/12/18 12:45:08 ru Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISBLANK 3 .Os .Sh NAME @@ -48,6 +48,15 @@ The .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 +In the "C" locale +.Fn isblank +successful test is limited to this characters only. For single C .Va char Ns s locales (see @@ -57,6 +66,17 @@ representable as an .Li unsigned char or the value of .Dv EOF . +.Sh COMPATIBILITY +Although +.Fn isblank +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswblank +function should be used instead for maximum portability. .Sh RETURN VALUES The .Fn isblank @@ -64,5 +84,12 @@ function returns zero if the character tests false and returns non-zero if the character tests true. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswblank 3 , .Xr multibyte 3 , .Xr ascii 7 +.Sh STANDARDS +The +.Fn isblank +function +conforms to +.St -isoC-99 . diff --git a/locale/iscntrl.3 b/locale/FreeBSD/iscntrl.3 similarity index 79% rename from locale/iscntrl.3 rename to locale/FreeBSD/iscntrl.3 index be6dcc5..6024c0e 100644 --- a/locale/iscntrl.3 +++ b/locale/FreeBSD/iscntrl.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)iscntrl.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/iscntrl.3,v 1.6.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/iscntrl.3,v 1.15 2002/12/05 08:50:00 ru Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISCNTRL 3 .Os .Sh NAME @@ -65,21 +65,33 @@ 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 "\&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" +.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 +Although +.Fn iscntrl +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iwcntrl +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswcntrl 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isctype.c b/locale/FreeBSD/isctype.c similarity index 81% rename from locale/isctype.c rename to locale/FreeBSD/isctype.c index 7c718c7..d718b77 100644 --- a/locale/isctype.c +++ b/locale/FreeBSD/isctype.c @@ -37,13 +37,13 @@ * LIABILITY, OR TORT (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/isctype.c,v 1.7 2000/02/08 07:43:24 obrien Exp $ */ #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 @@ -52,7 +52,7 @@ int digittoint(c) int c; { - return (__maskrune((c), 0xFF)); + return (__maskrune(c, 0xFF)); } #undef isalnum @@ -60,7 +60,7 @@ int isalnum(c) int c; { - return (__istype((c), _CTYPE_A|_CTYPE_D)); + return (__istype(c, _CTYPE_A|_CTYPE_D)); } #undef isalpha @@ -68,7 +68,7 @@ int isalpha(c) int c; { - return (__istype((c), _CTYPE_A)); + return (__istype(c, _CTYPE_A)); } #undef isascii @@ -76,7 +76,7 @@ int isascii(c) int c; { - return (((c) & ~0x7F) == 0); + return ((c & ~0x7F) == 0); } #undef isblank @@ -84,7 +84,7 @@ int isblank(c) int c; { - return (__istype((c), _CTYPE_B)); + return (__istype(c, _CTYPE_B)); } #undef iscntrl @@ -92,7 +92,7 @@ int iscntrl(c) int c; { - return (__istype((c), _CTYPE_C)); + return (__istype(c, _CTYPE_C)); } #undef isdigit @@ -100,7 +100,7 @@ int isdigit(c) int c; { - return (__isctype((c), _CTYPE_D)); + return (__isctype(c, _CTYPE_D)); } #undef isgraph @@ -108,7 +108,7 @@ int isgraph(c) int c; { - return (__istype((c), _CTYPE_G)); + return (__istype(c, _CTYPE_G)); } #undef ishexnumber @@ -116,7 +116,7 @@ int ishexnumber(c) int c; { - return (__istype((c), _CTYPE_X)); + return (__istype(c, _CTYPE_X)); } #undef isideogram @@ -124,7 +124,7 @@ int isideogram(c) int c; { - return (__istype((c), _CTYPE_I)); + return (__istype(c, _CTYPE_I)); } #undef islower @@ -132,7 +132,7 @@ int islower(c) int c; { - return (__istype((c), _CTYPE_L)); + return (__istype(c, _CTYPE_L)); } #undef isnumber @@ -140,7 +140,7 @@ int isnumber(c) int c; { - return (__istype((c), _CTYPE_D)); + return (__istype(c, _CTYPE_D)); } #undef isphonogram @@ -148,7 +148,7 @@ int isphonogram(c) int c; { - return (__istype((c), _CTYPE_Q)); + return (__istype(c, _CTYPE_Q)); } #undef isprint @@ -156,7 +156,7 @@ int isprint(c) int c; { - return (__istype((c), _CTYPE_R)); + return (__istype(c, _CTYPE_R)); } #undef ispunct @@ -164,7 +164,7 @@ int ispunct(c) int c; { - return (__istype((c), _CTYPE_P)); + return (__istype(c, _CTYPE_P)); } #undef isrune @@ -172,7 +172,7 @@ int isrune(c) int c; { - return (__istype((c), 0xFFFFFF00L)); + return (__istype(c, 0xFFFFFF00L)); } #undef isspace @@ -180,7 +180,7 @@ int isspace(c) int c; { - return (__istype((c), _CTYPE_S)); + return (__istype(c, _CTYPE_S)); } #undef isspecial @@ -188,7 +188,7 @@ int isspecial(c) int c; { - return (__istype((c), _CTYPE_T)); + return (__istype(c, _CTYPE_T)); } #undef isupper @@ -196,7 +196,7 @@ int isupper(c) int c; { - return (__istype((c), _CTYPE_U)); + return (__istype(c, _CTYPE_U)); } #undef isxdigit @@ -204,7 +204,7 @@ int isxdigit(c) int c; { - return (__isctype((c), _CTYPE_X)); + return (__isctype(c, _CTYPE_X)); } #undef toascii @@ -212,7 +212,7 @@ int toascii(c) int c; { - return ((c) & 0x7F); + return (c & 0x7F); } #undef tolower diff --git a/locale/isdigit.3 b/locale/FreeBSD/isdigit.3 similarity index 80% rename from locale/isdigit.3 rename to locale/FreeBSD/isdigit.3 index 9042f31..8fecc59 100644 --- a/locale/isdigit.3 +++ b/locale/FreeBSD/isdigit.3 @@ -34,13 +34,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)isdigit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isdigit.3,v 1.6.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isdigit.3,v 1.16 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISDIGIT 3 .Os .Sh NAME -.Nm isdigit +.Nm isdigit, isnumber .Nd decimal-digit character test .Sh LIBRARY .Lb libc @@ -48,10 +48,20 @@ .In ctype.h .Ft int .Fn isdigit "int c" +.Ft int +.Fn isnumber "int c" .Sh DESCRIPTION The .Fn isdigit function tests for any decimal-digit character. +For any 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 For single C .Va char Ns s locales (see @@ -61,20 +71,25 @@ 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 "\&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''" -.It "\&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''" -.El .Sh RETURN VALUES The .Fn isdigit function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn isdigit +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswdigit +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswdigit 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isgraph.3 b/locale/FreeBSD/isgraph.3 similarity index 89% rename from locale/isgraph.3 rename to locale/FreeBSD/isgraph.3 index 02e7b13..6975930 100644 --- a/locale/isgraph.3 +++ b/locale/FreeBSD/isgraph.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isgraph.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/locale/isgraph.3,v 1.7.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isgraph.3,v 1.17 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd December 11, 1993 +.Dd October 6, 2002 .Dt ISGRAPH 3 .Os .Sh NAME @@ -51,7 +51,10 @@ .Sh DESCRIPTION The .Fn isgraph -function tests for any printing character except space. +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 @@ -90,8 +93,20 @@ The .Fn isgraph function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn isgraph +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswgraph +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswgraph 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/islower.3 b/locale/FreeBSD/islower.3 similarity index 89% rename from locale/islower.3 rename to locale/FreeBSD/islower.3 index 95358f7..7fb642c 100644 --- a/locale/islower.3 +++ b/locale/FreeBSD/islower.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)islower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/islower.3,v 1.7.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/islower.3,v 1.15 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISLOWER 3 .Os .Sh NAME @@ -77,8 +77,20 @@ The .Fn islower function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn islower +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswlower +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswlower 3 , .Xr multibyte 3 , .Xr tolower 3 , .Xr ascii 7 diff --git a/locale/isprint.3 b/locale/FreeBSD/isprint.3 similarity index 90% rename from locale/isprint.3 rename to locale/FreeBSD/isprint.3 index 3f281fe..ed2ce3d 100644 --- a/locale/isprint.3 +++ b/locale/FreeBSD/isprint.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isprint.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isprint.3,v 1.7.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isprint.3,v 1.18 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISPRINT 3 .Os .Sh NAME @@ -51,7 +51,8 @@ .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 @@ -90,8 +91,20 @@ The .Fn isprint function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn isprint +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswprint +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswprint 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/ispunct.3 b/locale/FreeBSD/ispunct.3 similarity index 88% rename from locale/ispunct.3 rename to locale/FreeBSD/ispunct.3 index 3d17042..67fe6a3 100644 --- a/locale/ispunct.3 +++ b/locale/FreeBSD/ispunct.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ispunct.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/ispunct.3,v 1.7.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/ispunct.3,v 1.16 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISPUNCT 3 .Os .Sh NAME @@ -51,7 +51,9 @@ .Sh DESCRIPTION The .Fn ispunct -function tests for any printing character except for space (' ') or a +function tests for any printing character except for space +.Pq Ql "\ " +or a character for which .Xr isalnum 3 is true. @@ -81,8 +83,20 @@ The .Fn ispunct function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn ispunct +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswpunct +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswpunct 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isspace.3 b/locale/FreeBSD/isspace.3 similarity index 78% rename from locale/isspace.3 rename to locale/FreeBSD/isspace.3 index b53b3f9..eab4f5d 100644 --- a/locale/isspace.3 +++ b/locale/FreeBSD/isspace.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isspace.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isspace.3,v 1.6.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isspace.3,v 1.15 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISSPACE 3 .Os .Sh NAME @@ -51,7 +51,16 @@ .Sh DESCRIPTION The .Fn isspace -function tests for the standard white-space characters. +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 this characters only. For single C .Va char Ns s locales (see @@ -61,20 +70,25 @@ 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 "\&011\ ht \t012\ nl \t013\ vt \t014\ np \t015\ cr" -.It "\&040\ sp" -.El .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 +Although +.Fn isspace +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswspace +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswspace 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/isupper.3 b/locale/FreeBSD/isupper.3 similarity index 89% rename from locale/isupper.3 rename to locale/FreeBSD/isupper.3 index af98c6b..09070df 100644 --- a/locale/isupper.3 +++ b/locale/FreeBSD/isupper.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)isupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isupper.3,v 1.8.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isupper.3,v 1.16 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISUPPER 3 .Os .Sh NAME @@ -77,8 +77,20 @@ The .Fn isupper function returns zero if the character tests false and returns non-zero if the character tests true. +.Sh COMPATIBILITY +Although +.Fn isupper +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn iswupper +function should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswupper 3 , .Xr multibyte 3 , .Xr toupper 3 , .Xr ascii 7 diff --git a/locale/FreeBSD/iswalnum.3 b/locale/FreeBSD/iswalnum.3 new file mode 100644 index 0000000..4aafb25 --- /dev/null +++ b/locale/FreeBSD/iswalnum.3 @@ -0,0 +1,162 @@ +.\" $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 (like +.Xr isalnum 3 ) , +for details. +.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 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/locale/FreeBSD/iswctype.c b/locale/FreeBSD/iswctype.c new file mode 100644 index 0000000..37e2656 --- /dev/null +++ b/locale/FreeBSD/iswctype.c @@ -0,0 +1,214 @@ +/* + * 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 + +#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)); +} + +#undef iswhexnumber +int +iswhexnumber(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_X)); +} + +#undef iswideogram +int +iswideogram(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_I)); +} + +#undef iswlower +int +iswlower(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_L)); +} + +#undef iswnumber +int +iswnumber(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_D)); +} + +#undef iswphonogram +int +iswphonogram(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_Q)); +} + +#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/isxdigit.3 b/locale/FreeBSD/isxdigit.3 similarity index 76% rename from locale/isxdigit.3 rename to locale/FreeBSD/isxdigit.3 index 7fa9ceb..9520826 100644 --- a/locale/isxdigit.3 +++ b/locale/FreeBSD/isxdigit.3 @@ -34,13 +34,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)isxdigit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/isxdigit.3,v 1.6.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/isxdigit.3,v 1.16 2002/10/06 10:15:38 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt ISXDIGIT 3 .Os .Sh NAME -.Nm isxdigit +.Nm isxdigit, ishexnumber .Nd hexadecimal-digit character test .Sh LIBRARY .Lb libc @@ -48,10 +48,22 @@ .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. +For any 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 For single C .Va char Ns s locales (see @@ -61,23 +73,29 @@ 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 "\&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'' \t141\ ``a'' \t142\ ``b'' \t143\ ``c'' \t144\ ``d''" -.It "\&145\ ``e'' \t146\ ``f''" -.El .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 +Although +.Fn isxdigit +and +.Fn ishexnumber +accept arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn isxwdigit +and +.Fn iswhexnumber +functions should be used instead for maximum portability. .Sh SEE ALSO .Xr ctype 3 , +.Xr iswxdigit 3 , .Xr multibyte 3 , .Xr ascii 7 .Sh STANDARDS diff --git a/locale/FreeBSD/ldpart.c b/locale/FreeBSD/ldpart.c new file mode 100644 index 0000000..fc60b19 --- /dev/null +++ b/locale/FreeBSD/ldpart.c @@ -0,0 +1,161 @@ +/* + * 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.12 2002/10/27 17:44:33 wollman Exp $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "setlocale.h" +#include "ldpart.h" + +static int split_lines(char *, const char *); + +int +__part_load_locale(const char *name, + int *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; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + *using_locale = 0; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (locale_buf != NULL && strcmp(name, locale_buf) == 0) { + *using_locale = 1; + return (_LDP_CACHE); + } + + /* + * 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; + + for (i = 0; p < plim; i++) { + p = strchr(p, '\n'); + *p++ = '\0'; + } + return (i); +} + diff --git a/locale/FreeBSD/ldpart.c.patch b/locale/FreeBSD/ldpart.c.patch new file mode 100644 index 0000000..19e299c --- /dev/null +++ b/locale/FreeBSD/ldpart.c.patch @@ -0,0 +1,35 @@ +--- ldpart.c.orig Tue May 20 15:21:44 2003 ++++ ldpart.c Wed Jun 11 13:11:52 2003 +@@ -47,7 +47,7 @@ + int + __part_load_locale(const char *name, + int *using_locale, +- char *locale_buf, ++ char **locale_buf, + const char *category_filename, + int locale_buf_size_max, + int locale_buf_size_min, +@@ -69,7 +69,7 @@ + /* + * If the locale name is the same as our cache, use the cache. + */ +- if (locale_buf != NULL && strcmp(name, locale_buf) == 0) { ++ if (*locale_buf != NULL && strcmp(name, *locale_buf) == 0) { + *using_locale = 1; + return (_LDP_CACHE); + } +@@ -124,10 +124,10 @@ + /* + * 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++) ++ 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; diff --git a/locale/FreeBSD/ldpart.h b/locale/FreeBSD/ldpart.h new file mode 100644 index 0000000..8b45014 --- /dev/null +++ b/locale/FreeBSD/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.5 2002/08/08 05:51:54 ache 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 *, int*, char *, const char *, + int, int, const char **); + +#endif /* !_LDPART_H_ */ diff --git a/locale/FreeBSD/ldpart.h.patch b/locale/FreeBSD/ldpart.h.patch new file mode 100644 index 0000000..0b16e03 --- /dev/null +++ b/locale/FreeBSD/ldpart.h.patch @@ -0,0 +1,11 @@ +--- ldpart.h.orig Tue May 20 15:21:44 2003 ++++ ldpart.h Wed Jun 11 13:12:07 2003 +@@ -33,7 +33,7 @@ + #define _LDP_ERROR (-1) + #define _LDP_CACHE 1 + +-int __part_load_locale(const char *, int*, char *, const char *, ++int __part_load_locale(const char *, int*, char **, const char *, + int, int, const char **); + + #endif /* !_LDPART_H_ */ diff --git a/locale/FreeBSD/lmessages.c b/locale/FreeBSD/lmessages.c new file mode 100644 index 0000000..364beab --- /dev/null +++ b/locale/FreeBSD/lmessages.c @@ -0,0 +1,91 @@ +/* + * 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.12 2002/08/08 05:51:54 ache Exp $"); + +#include + +#include "lmessages.h" +#include "ldpart.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 */ +}; + +static struct lc_messages_T _messages_locale; +static int _messages_using_locale; +static char *_messages_locale_buf; + +int +__messages_load_locale(const char *name) +{ + int ret; + + ret = __part_load_locale(name, &_messages_using_locale, + _messages_locale_buf, "LC_MESSAGES", + LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN, + (const char **)&_messages_locale); + if (ret == _LDP_LOADED) { + if (_messages_locale.yesstr == NULL) + _messages_locale.yesstr = empty; + if (_messages_locale.nostr == NULL) + _messages_locale.nostr = empty; + } + return (ret); +} + +struct lc_messages_T * +__get_current_messages_locale(void) +{ + return (_messages_using_locale + ? &_messages_locale + : (struct lc_messages_T *)&_C_messages_locale); +} + +#ifdef LOCALE_DEBUG +void +msgdebug() { +printf( "yesexpr = %s\n" + "noexpr = %s\n" + "yesstr = %s\n" + "nostr = %s\n", + _messages_locale.yesexpr, + _messages_locale.noexpr, + _messages_locale.yesstr, + _messages_locale.nostr +); +} +#endif /* LOCALE_DEBUG */ diff --git a/locale/FreeBSD/lmessages.c.patch b/locale/FreeBSD/lmessages.c.patch new file mode 100644 index 0000000..0945992 --- /dev/null +++ b/locale/FreeBSD/lmessages.c.patch @@ -0,0 +1,11 @@ +--- lmessages.c.orig Tue May 20 15:21:44 2003 ++++ lmessages.c Wed Jun 11 13:13:38 2003 +@@ -55,7 +55,7 @@ + int ret; + + ret = __part_load_locale(name, &_messages_using_locale, +- _messages_locale_buf, "LC_MESSAGES", ++ &_messages_locale_buf, "LC_MESSAGES/LC_MESSAGES", + LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN, + (const char **)&_messages_locale); + if (ret == _LDP_LOADED) { diff --git a/locale/FreeBSD/lmessages.h b/locale/FreeBSD/lmessages.h new file mode 100644 index 0000000..ee690ae --- /dev/null +++ b/locale/FreeBSD/lmessages.h @@ -0,0 +1,42 @@ +/*- + * 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_ + +struct lc_messages_T { + const char *yesexpr; + const char *noexpr; + const char *yesstr; + const char *nostr; +}; + +struct lc_messages_T *__get_current_messages_locale(void); +int __messages_load_locale(const char *); + +#endif /* !_LMESSAGES_H_ */ diff --git a/locale/FreeBSD/lmonetary.c b/locale/FreeBSD/lmonetary.c new file mode 100644 index 0000000..563dee6 --- /dev/null +++ b/locale/FreeBSD/lmonetary.c @@ -0,0 +1,179 @@ +/* + * 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.17 2002/10/12 11:31:07 ache Exp $"); + +#include +#include +#include +#include "lmonetary.h" +#include "ldpart.h" + +extern int __mlocale_changed; +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 */ + numempty, /* mon_grouping */ + 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 struct lc_monetary_T _monetary_locale; +static int _monetary_using_locale; +static char *_monetary_locale_buf; + +static char +cnv(const char *str) +{ + int i = strtol(str, NULL, 10); + + if (i == -1) + i = CHAR_MAX; + return ((char)i); +} + +int +__monetary_load_locale(const char *name) +{ + int ret; + + ret = __part_load_locale(name, &_monetary_using_locale, + _monetary_locale_buf, "LC_MONETARY", + LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, + (const char **)&_monetary_locale); + if (ret != _LDP_ERROR) + __mlocale_changed = 1; + if (ret == _LDP_LOADED) { + _monetary_locale.mon_grouping = + __fix_locale_grouping_str(_monetary_locale.mon_grouping); + +#define M_ASSIGN_CHAR(NAME) (((char *)_monetary_locale.NAME)[0] = \ + cnv(_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 4 LC_MONETARY data files. + */ +#define M_ASSIGN_ICHAR(NAME) \ + do { \ + if (_monetary_locale.int_##NAME == NULL) \ + _monetary_locale.int_##NAME = \ + _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); + } + return (ret); +} + +struct lc_monetary_T * +__get_current_monetary_locale(void) +{ + return (_monetary_using_locale + ? &_monetary_locale + : (struct lc_monetary_T *)&_C_monetary_locale); +} + +#ifdef LOCALE_DEBUG +void +monetdebug() { +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", + _monetary_locale.int_curr_symbol, + _monetary_locale.currency_symbol, + _monetary_locale.mon_decimal_point, + _monetary_locale.mon_thousands_sep, + _monetary_locale.mon_grouping, + _monetary_locale.positive_sign, + _monetary_locale.negative_sign, + _monetary_locale.int_frac_digits[0], + _monetary_locale.frac_digits[0], + _monetary_locale.p_cs_precedes[0], + _monetary_locale.p_sep_by_space[0], + _monetary_locale.n_cs_precedes[0], + _monetary_locale.n_sep_by_space[0], + _monetary_locale.p_sign_posn[0], + _monetary_locale.n_sign_posn[0] +); +} +#endif /* LOCALE_DEBUG */ diff --git a/locale/FreeBSD/lmonetary.c.patch b/locale/FreeBSD/lmonetary.c.patch new file mode 100644 index 0000000..de1410d --- /dev/null +++ b/locale/FreeBSD/lmonetary.c.patch @@ -0,0 +1,11 @@ +--- lmonetary.c.orig Tue May 20 15:21:44 2003 ++++ lmonetary.c Wed Jun 11 13:12:44 2003 +@@ -88,7 +88,7 @@ + int ret; + + ret = __part_load_locale(name, &_monetary_using_locale, +- _monetary_locale_buf, "LC_MONETARY", ++ &_monetary_locale_buf, "LC_MONETARY", + LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, + (const char **)&_monetary_locale); + if (ret != _LDP_ERROR) diff --git a/locale/FreeBSD/lmonetary.h b/locale/FreeBSD/lmonetary.h new file mode 100644 index 0000000..e278ea5 --- /dev/null +++ b/locale/FreeBSD/lmonetary.h @@ -0,0 +1,59 @@ +/*- + * 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_ + +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(void); +int __monetary_load_locale(const char *); + +#endif /* !_LMONETARY_H_ */ diff --git a/locale/FreeBSD/lnumeric.c b/locale/FreeBSD/lnumeric.c new file mode 100644 index 0000000..8dcdaa1 --- /dev/null +++ b/locale/FreeBSD/lnumeric.c @@ -0,0 +1,92 @@ +/* + * 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.14 2003/03/20 08:05:20 ache Exp $"); + +#include +#include "lnumeric.h" +#include "ldpart.h" + +extern int __nlocale_changed; +extern const char *__fix_locale_grouping_str(const char *); + +#define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *)) + +static char numempty[] = { CHAR_MAX, '\0' }; + +static const struct lc_numeric_T _C_numeric_locale = { + ".", /* decimal_point */ + "", /* thousands_sep */ + numempty /* grouping */ +}; + +static struct lc_numeric_T _numeric_locale; +static int _numeric_using_locale; +static char *_numeric_locale_buf; + +int +__numeric_load_locale(const char *name) +{ + int ret; + + ret = __part_load_locale(name, &_numeric_using_locale, + _numeric_locale_buf, "LC_NUMERIC", + LCNUMERIC_SIZE, LCNUMERIC_SIZE, + (const char **)&_numeric_locale); + if (ret != _LDP_ERROR) + __nlocale_changed = 1; + if (ret == _LDP_LOADED) { + /* Can't be empty according to C99 */ + if (*_numeric_locale.decimal_point == '\0') + _numeric_locale.decimal_point = + _C_numeric_locale.decimal_point; + _numeric_locale.grouping = + __fix_locale_grouping_str(_numeric_locale.grouping); + } + return (ret); +} + +struct lc_numeric_T * +__get_current_numeric_locale(void) +{ + return (_numeric_using_locale + ? &_numeric_locale + : (struct lc_numeric_T *)&_C_numeric_locale); +} + +#ifdef LOCALE_DEBUG +void +numericdebug(void) { +printf( "decimal_point = %s\n" + "thousands_sep = %s\n" + "grouping = %s\n", + _numeric_locale.decimal_point, + _numeric_locale.thousands_sep, + _numeric_locale.grouping +); +} +#endif /* LOCALE_DEBUG */ diff --git a/locale/FreeBSD/lnumeric.c.patch b/locale/FreeBSD/lnumeric.c.patch new file mode 100644 index 0000000..545cfef --- /dev/null +++ b/locale/FreeBSD/lnumeric.c.patch @@ -0,0 +1,11 @@ +--- lnumeric.c.orig Tue May 20 15:21:44 2003 ++++ lnumeric.c Wed Jun 11 13:13:11 2003 +@@ -54,7 +54,7 @@ + int ret; + + ret = __part_load_locale(name, &_numeric_using_locale, +- _numeric_locale_buf, "LC_NUMERIC", ++ &_numeric_locale_buf, "LC_NUMERIC", + LCNUMERIC_SIZE, LCNUMERIC_SIZE, + (const char **)&_numeric_locale); + if (ret != _LDP_ERROR) diff --git a/locale/FreeBSD/lnumeric.h b/locale/FreeBSD/lnumeric.h new file mode 100644 index 0000000..9678c1f --- /dev/null +++ b/locale/FreeBSD/lnumeric.h @@ -0,0 +1,41 @@ +/*- + * 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_ + +struct lc_numeric_T { + const char *decimal_point; + const char *thousands_sep; + const char *grouping; +}; + +struct lc_numeric_T *__get_current_numeric_locale(void); +int __numeric_load_locale(const char *); + +#endif /* !_LNUMERIC_H_ */ diff --git a/locale/FreeBSD/localeconv.c b/locale/FreeBSD/localeconv.c new file mode 100644 index 0000000..ab949bc --- /dev/null +++ b/locale/FreeBSD/localeconv.c @@ -0,0 +1,111 @@ +/* + * 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.12 2002/10/09 09:19:28 tjr Exp $"); + +#include +#include "lmonetary.h" +#include "lnumeric.h" + +/* + * 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. + */ +int __mlocale_changed = 1; +int __nlocale_changed = 1; + +/* + * Return the current locale conversion. + */ +struct lconv * +localeconv() +{ + static struct lconv ret; + + if (__mlocale_changed) { + /* LC_MONETARY part */ + struct lc_monetary_T * mptr; + +#define M_ASSIGN_STR(NAME) (ret.NAME = (char*)mptr->NAME) +#define M_ASSIGN_CHAR(NAME) (ret.NAME = mptr->NAME[0]) + + mptr = __get_current_monetary_locale(); + 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); + __mlocale_changed = 0; + } + + if (__nlocale_changed) { + /* LC_NUMERIC part */ + struct lc_numeric_T * nptr; + +#define N_ASSIGN_STR(NAME) (ret.NAME = (char*)nptr->NAME) + + nptr = __get_current_numeric_locale(); + N_ASSIGN_STR(decimal_point); + N_ASSIGN_STR(thousands_sep); + N_ASSIGN_STR(grouping); + __nlocale_changed = 0; + } + + return (&ret); +} diff --git a/locale/FreeBSD/localeconv.c.patch b/locale/FreeBSD/localeconv.c.patch new file mode 100644 index 0000000..d2a1cfb --- /dev/null +++ b/locale/FreeBSD/localeconv.c.patch @@ -0,0 +1,83 @@ +--- localeconv.c.orig Tue May 20 15:21:44 2003 ++++ localeconv.c Thu Sep 11 13:52:19 2003 +@@ -38,10 +38,66 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.12 2002/10/09 09:19:28 tjr Exp $"); + ++#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. +@@ -61,6 +117,13 @@ + localeconv() + { + static struct lconv ret; ++ ++ /*-------------------------------------------------------------------- ++ * If _onlyClocaleconv is non-zero, just return __lconv, which is a "C" ++ * struct lconv *. Otherwise, do the normal thing. ++ *--------------------------------------------------------------------*/ ++ if (_onlyClocaleconv) ++ return &_C_lconv; + + if (__mlocale_changed) { + /* LC_MONETARY part */ diff --git a/locale/FreeBSD/mblen.c b/locale/FreeBSD/mblen.c new file mode 100644 index 0000000..82e0658 --- /dev/null +++ b/locale/FreeBSD/mblen.c @@ -0,0 +1,58 @@ +/*- + * 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/mblen.c,v 1.4 2002/10/28 08:24:46 tjr Exp $"); + +#include +#include +#include +#include + +int +mblen(const char *s, size_t n) +{ + const char *e; + + if (s == NULL) + /* No support for state dependent encodings. */ + return (0); + if (sgetrune(s, n, &e) == _INVALID_RUNE) { + errno = EILSEQ; + return (-1); + } + return (*s == '\0' ? 0 : e - s); +} diff --git a/locale/FreeBSD/mbrlen.3 b/locale/FreeBSD/mbrlen.3 new file mode 100644 index 0000000..a1898d5 --- /dev/null +++ b/locale/FreeBSD/mbrlen.3 @@ -0,0 +1,145 @@ +.\" 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/mbrlen.3,v 1.6 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd November 11, 2002 +.Dt MBRLEN 3 +.Os +.Sh NAME +.Nm mbrlen +.Nd "get number of bytes in a character (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fn mbrlen "const char * restrict s" "size_t n" "mbstate_t * restrict ps" +.Sh DESCRIPTION +The +.Fn mbrlen +function determines the number of bytes constituting the +multibyte character sequence pointed to by +.Fa s , +examining at most +.Fa n +bytes. +.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. +.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. +.Sh RETURN VALUES +The +.Fn mbrlen +functions returns: +.Bl -tag -width indent +.It 0 +The first +.Fa n +or fewer bytes of +.Fa s +represent the null wide character +.Pq Li "L'\e0'" . +.It >0 +The first +.Fa n +or fewer bytes of +.Fa s +represent a valid character, +.Fn mbrtowc +returns the length (in bytes) of the multibyte sequence. +.It Po Vt size_t Pc Ns \-2 +The first +.Fa n +bytes of +.Fa s +are an incomplete multibyte sequence. +.It Po Vt size_t Pc Ns \-1 +The byte sequence pointed to by +.Fa s +is an invalid multibyte sequence. +.El +.Sh EXAMPLES +A function which 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 EINVAL +.\"Invalid argument. +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.El +.Sh SEE ALSO +.Xr mblen 3 , +.Xr mbrtowc 3 +.Sh STANDARDS +The +.Fn mbrlen +function conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation does not support shift states. diff --git a/locale/FreeBSD/mbrlen.c b/locale/FreeBSD/mbrlen.c new file mode 100644 index 0000000..0d49fe5 --- /dev/null +++ b/locale/FreeBSD/mbrlen.c @@ -0,0 +1,37 @@ +/*- + * 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/mbrlen.c,v 1.2 2002/09/06 11:23:45 tjr Exp $"); + +#include + +size_t +mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused) +{ + + return (mbrtowc(NULL, s, n, NULL)); +} diff --git a/locale/FreeBSD/mbrtowc.3 b/locale/FreeBSD/mbrtowc.3 new file mode 100644 index 0000000..adbc66a --- /dev/null +++ b/locale/FreeBSD/mbrtowc.3 @@ -0,0 +1,140 @@ +.\" 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/mbrtowc.3,v 1.3 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd August 15, 2002 +.Dt MBRTOWC 3 +.Os +.Sh NAME +.Nm mbrtowc +.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" "const char * restrict s" "size_t n" +.Fa "mbstate_t * restrict ps" +.Fc +.Sh DESCRIPTION +The +.Fn mbrtowc +function inspects at most +.Fa n +bytes pointed to by +.Fa s +and interprets them as a multibyte character sequence +according to the current setting of +.Ev LC_CTYPE . +If +.Fa pwc +is not +.Dv NULL , +the multibyte character which +.Fa s +represents is stored in the +.Vt wchar_t +it points to. +.Pp +If +.Fa s +is +.Dv NULL , +.Fn mbrtowc +behaves as if +.Fa pwc +was +.Dv NULL , +.Fa s +was an empty string +.Pq Qq +and +.Fa n +was 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. +.Sh RETURN VALUES +The +.Fn mbrtowc +functions returns: +.Bl -tag -width indent +.It 0 +The first +.Fa n +or fewer bytes of +.Fa s +represent the null wide character +.Pq Li "L'\e0'" . +.It >0 +The first +.Fa n +or fewer bytes of +.Fa s +represent a valid character, +.Fn mbrtowc +returns the length (in bytes) of the multibyte sequence. +.It Po Vt size_t Pc Ns \-2 +The first +.Fa n +bytes of +.Fa s +are an incomplete multibyte sequence. +.It Po Vt size_t Pc Ns \-1 +The byte sequence pointed to by +.Fa s +is an invalid multibyte sequence. +.El +.Sh ERRORS +The +.Fn mbrtowc +function will fail if: +.Bl -tag -width Er +.\".It Bq Er EINVAL +.\"Invalid argument. +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.El +.Sh SEE ALSO +.Xr mbtowc 3 , +.Xr setlocale 3 , +.Xr wcrtomb 3 +.Sh STANDARDS +The +.Fn mbrtowc +function conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation does not support shift states. diff --git a/locale/FreeBSD/mbrtowc.c b/locale/FreeBSD/mbrtowc.c new file mode 100644 index 0000000..a3b2dd6 --- /dev/null +++ b/locale/FreeBSD/mbrtowc.c @@ -0,0 +1,75 @@ +/*- + * 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/mbrtowc.c,v 1.3 2002/11/10 10:49:14 tjr Exp $"); + +#include +#include +#include +#include + +size_t +mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused) +{ + const char *e; + rune_t r; + + if (s == NULL) { + pwc = NULL; + s = ""; + n = 1; + } + + if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) { + /* + * The design of sgetrune() doesn't give us any way to tell + * between incomplete and invalid multibyte sequences. + */ + + if (n >= (size_t)MB_CUR_MAX) { + /* + * If we have been supplied with at least MB_CUR_MAX + * bytes and still cannot find a valid character, the + * data must be invalid. + */ + errno = EILSEQ; + return ((size_t)-1); + } + + /* + * .. otherwise, it's an incomplete character or an invalid + * character we cannot detect yet. + */ + return ((size_t)-2); + } + + if (pwc != NULL) + *pwc = (wchar_t)r; + + return (r != 0 ? (size_t)(e - s) : 0); +} diff --git a/locale/mbrune.3 b/locale/FreeBSD/mbrune.3 similarity index 89% rename from locale/mbrune.3 rename to locale/FreeBSD/mbrune.3 index e6b6432..47fe006 100644 --- a/locale/mbrune.3 +++ b/locale/FreeBSD/mbrune.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)mbrune.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/locale/mbrune.3,v 1.6.2.4 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/mbrune.3,v 1.15 2003/02/06 11:04:46 charnier Exp $ .\" .Dd April 19, 1994 .Dt MBRUNE 3 @@ -54,6 +54,22 @@ .Ft char * .Fn mbmb "const char *string" "char *pattern" .Sh DESCRIPTION +.Bf Em +The +.Bx 4.4 +.Dq rune +functions have been deprecated in favour of the +.Tn ISO +C99 extended multibyte and wide character facilities +and should not be used in new applications. +.Ef +Consider working with wide characters instead, and using +.Xr wcschr 3 , +.Xr wcsrchr 3 , +and +.Xr wcsstr 3 +instead of these functions. +.Pp These routines provide the corresponding functionality of .Fn strchr , .Fn strrchr @@ -66,7 +82,7 @@ The function locates the first occurrence of .Fn rune in the string pointed to by -.Ar string . +.Fa string . The terminating .Dv NUL character is considered part of the string. @@ -140,12 +156,12 @@ or if the .Fa pattern does not appear in the string. -.Sh "SEE ALSO -.Xr mbrune 3 , +.Sh SEE ALSO .Xr rune 3 , .Xr setlocale 3 , .Xr euc 4 , -.Xr utf2 4 +.Xr utf2 4 , +.Xr utf8 5 .Sh HISTORY The .Fn mbrune , diff --git a/locale/mbrune.c b/locale/FreeBSD/mbrune.c similarity index 90% rename from locale/mbrune.c rename to locale/FreeBSD/mbrune.c index 92efe83..766516a 100644 --- a/locale/mbrune.c +++ b/locale/FreeBSD/mbrune.c @@ -37,12 +37,15 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)mbrune.c 8.1 (Berkeley) 6/27/93"; #endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbrune.c,v 1.3 2002/09/18 06:11:21 tjr Exp $"); #include #include #include #include +__warn_references(mbrune, "warning: mbrune() is deprecated. See mbrune(3)."); char * mbrune(string, c) const char *string; @@ -60,6 +63,7 @@ mbrune(string, c) return (c == *string ? (char *)string : NULL); } +__warn_references(mbrrune, "warning: mbrrune() is deprecated. See mbrrune(3)."); char * mbrrune(string, c) const char *string; @@ -77,6 +81,7 @@ mbrrune(string, c) return (c == *string ? (char *)string : (char *)last); } +__warn_references(mbmb, "warning: mbmb() is deprecated. See mbmb(3)."); char * mbmb(string, pattern) const char *string; diff --git a/locale/FreeBSD/mbsinit.3 b/locale/FreeBSD/mbsinit.3 new file mode 100644 index 0000000..bb382de --- /dev/null +++ b/locale/FreeBSD/mbsinit.3 @@ -0,0 +1,64 @@ +.\" 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/mbsinit.3,v 1.2 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd August 16, 2002 +.Dt MBSINIT 3 +.Os +.Sh NAME +.Nm mbsinit +.Nd "determine conversion object status" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fn mbsinit "const mbstate_t *ps" +.Sh DESCRIPTION +The +.Fn mbsinit +function determines whether the +.Vt mbstate_t +object pointed to by +.Fa ps +describes an initial conversion state. +.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 STANDARDS +The +.Fn mbsinit +function conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation does not support shift states; +.Fn mbsinit +always returns non-zero. diff --git a/locale/FreeBSD/mbsinit.c b/locale/FreeBSD/mbsinit.c new file mode 100644 index 0000000..2dd765e --- /dev/null +++ b/locale/FreeBSD/mbsinit.c @@ -0,0 +1,42 @@ +/*- + * 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/mbsinit.c,v 1.1 2002/08/18 06:30:10 tjr Exp $"); + +#include + +int +mbsinit(const mbstate_t *ps __unused) +{ + + /* + * Stateful multibyte conversion is not supported; there are no + * states other than the initial state. + */ + + return (1); +} diff --git a/locale/FreeBSD/mbsrtowcs.3 b/locale/FreeBSD/mbsrtowcs.3 new file mode 100644 index 0000000..661366a --- /dev/null +++ b/locale/FreeBSD/mbsrtowcs.3 @@ -0,0 +1,110 @@ +.\" 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/mbsrtowcs.3,v 1.3 2002/11/29 17:35:09 ru Exp $ +.Dd August 16, 2002 +.Dt MBSRTOWCS 3 +.Os +.Sh NAME +.Nm mbsrtowcs +.Nd "convert a character string to a wide-character string (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbsrtowcs +.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t len" +.Fa "mbstate_t * restrict ps" +.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 and 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. +.Sh RETURN VALUES +The +.Fn mbsrtowcs +function returns 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 +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte character sequence was encountered. +.El +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr mbstowcs 3 , +.Xr wcsrtombs 3 +.Sh STANDARDS +The +.Fn mbsrtowcs +function conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation does not support shift states. diff --git a/locale/FreeBSD/mbsrtowcs.c b/locale/FreeBSD/mbsrtowcs.c new file mode 100644 index 0000000..afff52f --- /dev/null +++ b/locale/FreeBSD/mbsrtowcs.c @@ -0,0 +1,74 @@ +/*- + * 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/mbsrtowcs.c,v 1.2 2002/09/06 11:23:45 tjr Exp $"); + +#include +#include +#include +#include + +size_t +mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len, + mbstate_t * __restrict ps __unused) +{ + const char *s; + size_t nchr; + wchar_t wc; + int nb; + + s = *src; + nchr = 0; + + if (dst == NULL) { + for (;;) { + if ((nb = (int)mbrtowc(&wc, s, MB_CUR_MAX, NULL)) < 0) + /* Invalid sequence - mbrtowc() sets errno. */ + return ((size_t)-1); + else if (nb == 0) + return (nchr); + s += nb; + nchr++; + } + /*NOTREACHED*/ + } + + while (len-- > 0) { + if ((nb = (int)mbrtowc(dst, s, MB_CUR_MAX, NULL)) < 0) { + *src = s; + return ((size_t)-1); + } else if (nb == 0) { + *src = NULL; + return (nchr); + } + s += nb; + nchr++; + dst++; + } + *src = s; + return (nchr); +} diff --git a/locale/FreeBSD/mbstowcs.c b/locale/FreeBSD/mbstowcs.c new file mode 100644 index 0000000..323c788 --- /dev/null +++ b/locale/FreeBSD/mbstowcs.c @@ -0,0 +1,88 @@ +/*- + * 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/mbstowcs.c,v 1.6 2002/11/09 04:13:26 tjr Exp $"); + +#include +#include +#include +#include +#include + +size_t +mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) +{ + const char *e; + int cnt; + rune_t r; + + if (s == NULL) { + errno = EINVAL; + return (-1); + } + + if (pwcs == NULL) { + /* Convert and count only, do not store. */ + cnt = 0; + while ((r = sgetrune(s, MB_LEN_MAX, &e)) != _INVALID_RUNE && + r != 0) { + s = e; + cnt++; + } + if (r == _INVALID_RUNE) { + errno = EILSEQ; + return (-1); + } + return (cnt); + } + + /* Convert, store and count characters. */ + cnt = 0; + while (n-- > 0) { + *pwcs = sgetrune(s, MB_LEN_MAX, &e); + if (*pwcs == _INVALID_RUNE) { + errno = EILSEQ; + return (-1); + } + if (*pwcs++ == L'\0') + break; + s = e; + ++cnt; + } + + return (cnt); +} diff --git a/locale/FreeBSD/mbtowc.c b/locale/FreeBSD/mbtowc.c new file mode 100644 index 0000000..b7182d0 --- /dev/null +++ b/locale/FreeBSD/mbtowc.c @@ -0,0 +1,61 @@ +/*- + * 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/mbtowc.c,v 1.6 2002/10/28 08:24:46 tjr Exp $"); + +#include +#include +#include +#include + +int +mbtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n) +{ + const char *e; + rune_t r; + + if (s == NULL) + /* No support for state dependent encodings. */ + return (0); + if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) { + errno = EILSEQ; + return (-1); + } + if (pwc != NULL) + *pwc = r; + return (r == 0 ? 0 : e - s); +} diff --git a/locale/mskanji.c b/locale/FreeBSD/mskanji.c similarity index 75% rename from locale/mskanji.c rename to locale/FreeBSD/mskanji.c index 16411f6..ce469c8 100644 --- a/locale/mskanji.c +++ b/locale/FreeBSD/mskanji.c @@ -29,13 +29,13 @@ * LIABILITY, OR TORT (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/mskanji.c,v 1.2.8.2 2001/03/05 10:22:45 obrien Exp $ */ #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.8 2002/10/14 01:50:45 tjr Exp $"); #include @@ -44,8 +44,8 @@ static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; #include #include -rune_t _MSKanji_sgetrune __P((const char *, size_t, char const **)); -int _MSKanji_sputrune __P((rune_t, char *, size_t, char **)); +rune_t _MSKanji_sgetrune(const char *, size_t, char const **); +int _MSKanji_sputrune(rune_t, char *, size_t, char **); int _MSKanji_init(rl) @@ -67,22 +67,25 @@ _MSKanji_sgetrune(string, n, result) { rune_t rune = 0; - if (n < 1 ) { - rune = _INVALID_RUNE; - } else { - rune = *( string++ ) & 0xff; - if ( ( rune > 0x80 && rune < 0xa0 ) - || ( rune >= 0xe0 && rune < 0xfa ) ) { - if ( n < 2 ) { - rune = (rune_t)_INVALID_RUNE; - --string; - } else { - rune = ( rune << 8 ) | ( *( string++ ) & 0xff ); - } - } + if (n < 1) { + if (result != NULL) + *result = string; + return (_INVALID_RUNE); + } + + rune = *string++ & 0xff; + if ((rune > 0x80 && rune < 0xa0) || + (rune >= 0xe0 && rune < 0xfd)) { + if (n < 2) { + rune = _INVALID_RUNE; + --string; + } else + rune = (rune << 8) | (*string++ & 0xff); } - if (result) *result = string; - return rune; + if (result != NULL) + *result = string; + + return (rune); } int @@ -91,16 +94,18 @@ _MSKanji_sputrune(c, string, n, result) char *string, **result; size_t n; { - int len, i; + int len, i; - len = ( c > 0x100 ) ? 2 : 1; - if ( n < len ) { - if ( result ) *result = (char *) 0; + len = (c > 0x100) ? 2 : 1; + if (n < len) { + if (result != NULL) + *result = NULL; } else { - if ( result ) *result = string + len; - for ( i = len; i-- > 0; ) { - *( string++ ) = c >> ( i << 3 ); - } + if (result != NULL) + *result = string + len; + for (i = len; i-- > 0; ) + *string++ = c >> (i << 3); } - return len; + + return (len); } diff --git a/locale/FreeBSD/mskanji.c.patch b/locale/FreeBSD/mskanji.c.patch new file mode 100644 index 0000000..f740c34 --- /dev/null +++ b/locale/FreeBSD/mskanji.c.patch @@ -0,0 +1,42 @@ +--- mskanji.c.orig Tue May 20 15:21:44 2003 ++++ mskanji.c Wed Jun 18 12:02:06 2003 +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + rune_t _MSKanji_sgetrune(const char *, size_t, char const **); + int _MSKanji_sputrune(rune_t, char *, size_t, char **); +@@ -67,20 +68,23 @@ + { + rune_t rune = 0; + +- if (n < 1) { +- if (result != NULL) +- *result = string; ++ if (result != NULL) ++ *result = string; ++ if (n < 1) + return (_INVALID_RUNE); +- } + + rune = *string++ & 0xff; + if ((rune > 0x80 && rune < 0xa0) || + (rune >= 0xe0 && rune < 0xfd)) { +- if (n < 2) { +- rune = _INVALID_RUNE; +- --string; +- } else ++ if (n < 2) ++ return (_INVALID_RUNE); ++ else + rune = (rune << 8) | (*string++ & 0xff); ++ } ++ if (!isrune(rune)) { ++ if (result != NULL) ++ (*result)++; ++ return (_INVALID_RUNE); + } + if (result != NULL) + *result = string; diff --git a/locale/multibyte.3 b/locale/FreeBSD/multibyte.3 similarity index 92% rename from locale/multibyte.3 rename to locale/FreeBSD/multibyte.3 index 84a3d0e..b2ba2cf 100644 --- a/locale/multibyte.3 +++ b/locale/FreeBSD/multibyte.3 @@ -33,9 +33,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)multibyte.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/multibyte.3,v 1.6.2.5 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/multibyte.3,v 1.19 2003/02/06 11:04:46 charnier Exp $ .\" -.Dd June 4, 1993 +.Dd October 6, 2002 .Dt MULTIBYTE 3 .Os .Sh NAME @@ -52,11 +52,11 @@ .Ft int .Fn mblen "const char *mbchar" "size_t nbytes" .Ft size_t -.Fn mbstowcs "wchar_t *wcstring" "const char *mbstring" "size_t nwchars" +.Fn mbstowcs "wchar_t * restrict wcstring" "const char * restrict mbstring" "size_t nwchars" .Ft int -.Fn mbtowc "wchar_t *wcharp" "const char *mbchar" "size_t nbytes" +.Fn mbtowc "wchar_t * restrict wcharp" "const char * restrict mbchar" "size_t nbytes" .Ft size_t -.Fn wcstombs "char *mbstring" "const wchar_t *wcstring" "size_t nbytes" +.Fn wcstombs "char * restrict mbstring" "const wchar_t * restrict wcstring" "size_t nbytes" .Ft int .Fn wctomb "char *mbchar" "wchar_t wchar" .Sh DESCRIPTION @@ -78,7 +78,7 @@ and code each basic element as a sequence of C .Va char Ns s . Individual basic elements may map into one or more (up to -.Dv MB_CHAR_MAX ) +.Dv MB_LEN_MAX ) bytes in a multibyte character. .Pp The current locale @@ -191,10 +191,6 @@ bytes are stored in Partial multibyte characters at the end of the string are not stored. The multibyte character string is null terminated if there is room. .Sh "RETURN VALUES -If multibyte characters are not supported in the current locale, -all of these functions will return \-1 if characters can be processed, -otherwise 0. -.Pp If .Fa mbchar is @@ -225,12 +221,19 @@ function returns the number of bytes converted, not counting any terminating null byte. If any invalid multibyte characters are encountered, both functions return \-1. -.Sh "SEE ALSO +.Sh SEE ALSO +.Xr btowc 3 , +.Xr mbrlen 3 , +.Xr mbrtowc 3 , .Xr mbrune 3 , +.Xr mbsrtowcs 3 , .Xr rune 3 , .Xr setlocale 3 , +.Xr wcrtomb 3 , +.Xr wcsrtombs 3 , .Xr euc 4 , -.Xr utf2 4 +.Xr utf2 4 , +.Xr utf8 5 .Sh STANDARDS The .Fn mblen , diff --git a/locale/nl_langinfo.3 b/locale/FreeBSD/nl_langinfo.3 similarity index 94% rename from locale/nl_langinfo.3 rename to locale/FreeBSD/nl_langinfo.3 index a4ddf96..96819e1 100644 --- a/locale/nl_langinfo.3 +++ b/locale/FreeBSD/nl_langinfo.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2001 Alexey Zelkin +.\" Copyright (c) 2001 Alexey Zelkin .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/nl_langinfo.3,v 1.2 2001/09/17 08:18:45 ache Exp $ +.\" $FreeBSD: src/lib/libc/locale/nl_langinfo.3,v 1.4 2002/04/13 04:25:56 dd Exp $ .\" .Dd May 3, 2001 .Dt NL_LANGINFO 3 @@ -87,4 +87,4 @@ function conforms to The .Fn nl_langinfo function first appeared in -.Fx 5.0 . +.Fx 4.6 . diff --git a/locale/FreeBSD/nl_langinfo.c b/locale/FreeBSD/nl_langinfo.c new file mode 100644 index 0000000..6cd0eda --- /dev/null +++ b/locale/FreeBSD/nl_langinfo.c @@ -0,0 +1,201 @@ +/*- + * 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/nl_langinfo.c,v 1.15 2002/03/22 21:52:18 obrien Exp $"); + +#include +#include +#include +#include +#include + +#include "../stdtime/timelocal.h" +#include "lnumeric.h" +#include "lmonetary.h" +#include "lmessages.h" + +#define TRANSITION_PERIOD_HACK + +#define _REL(BASE) ((int)item-BASE) + +char * +nl_langinfo(nl_item item) { + + char *ret, *s, *cs; + static char *csym = NULL; +#ifdef TRANSITION_PERIOD_HACK + static char *cset = NULL; +#endif /* TRANSITION_PERIOD_HACK */ + + switch (item) { + case CODESET: + ret = ""; + if ((s = setlocale(LC_CTYPE, NULL)) != NULL) { + if ((cs = strchr(s, '.')) != NULL) { + ret = cs + 1; +#ifdef TRANSITION_PERIOD_HACK + if (strncmp(ret, "ISO_", 4) == 0) { + int slen = strlen(ret); + + if ((cset = reallocf(cset, slen)) != NULL) { + strcpy(cset, "ISO"); + strcat(cset, ret + 4); + ret = cset; + } else + ret = ""; + } else if (strcmp(ret, "EUC") == 0) { + if (strncmp(s, "ja_JP", 5) == 0) + ret = "eucJP"; + else if (strncmp(s, "ko_KR", 5) == 0) + ret = "eucKR"; + else if (strncmp(s, "zh_CN", 5) == 0) + ret = "eucCN"; + } else if (strcmp(ret, "ASCII") == 0) + ret = "US-ASCII"; +#endif /* TRANSITION_PERIOD_HACK */ + } else if (strcmp(s, "C") == 0 || + strcmp(s, "POSIX") == 0 +#ifdef TRANSITION_PERIOD_HACK + || strstr(s, "ASCII") != NULL +#endif /* TRANSITION_PERIOD_HACK */ + ) + ret = "US-ASCII"; + } + break; + case D_T_FMT: + ret = (char *) __get_current_time_locale()->c_fmt; + break; + case D_FMT: + ret = (char *) __get_current_time_locale()->x_fmt; + break; + case T_FMT: + ret = (char *) __get_current_time_locale()->X_fmt; + break; + case T_FMT_AMPM: + ret = (char *) __get_current_time_locale()->ampm_fmt; + break; + case AM_STR: + ret = (char *) __get_current_time_locale()->am; + break; + case PM_STR: + ret = (char *) __get_current_time_locale()->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()->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()->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()->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()->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()->decimal_point; + break; + case THOUSEP: + ret = (char*) __get_current_numeric_locale()->thousands_sep; + break; + case YESEXPR: + ret = (char*) __get_current_messages_locale()->yesexpr; + break; + case NOEXPR: + ret = (char*) __get_current_messages_locale()->noexpr; + break; + /* + * All 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()->yesstr; + break; + case NOSTR: /* LEGACY */ + ret = (char*) __get_current_messages_locale()->nostr; + break; + case CRNCYSTR: + ret = ""; + cs = (char*) __get_current_monetary_locale()->currency_symbol; + if (*cs != '\0') { + char pos = localeconv()->p_cs_precedes; + + if (pos == localeconv()->n_cs_precedes) { + char psn = '\0'; + + if (pos == CHAR_MAX) { + if (strcmp(cs, __get_current_monetary_locale()->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: /* local extension */ + ret = (char *) __get_current_time_locale()->md_order; + break; + default: + ret = ""; + } + return (ret); +} diff --git a/locale/FreeBSD/nl_langinfo.c.patch b/locale/FreeBSD/nl_langinfo.c.patch new file mode 100644 index 0000000..a069542 --- /dev/null +++ b/locale/FreeBSD/nl_langinfo.c.patch @@ -0,0 +1,11 @@ +--- nl_langinfo.c.orig Fri Mar 22 13:52:18 2002 ++++ nl_langinfo.c Sat May 3 14:14:55 2003 +@@ -33,7 +33,7 @@ + #include + #include + +-#include "../stdtime/timelocal.h" ++#include "timelocal.h" + #include "lnumeric.h" + #include "lmonetary.h" + #include "lmessages.h" diff --git a/locale/nomacros.c b/locale/FreeBSD/nomacros.c similarity index 71% rename from locale/nomacros.c rename to locale/FreeBSD/nomacros.c index 45c0db7..eea37d0 100644 --- a/locale/nomacros.c +++ b/locale/FreeBSD/nomacros.c @@ -1,3 +1,6 @@ +#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 diff --git a/locale/none.c b/locale/FreeBSD/none.c similarity index 88% rename from locale/none.c rename to locale/FreeBSD/none.c index 4fb7d7e..2fd072d 100644 --- a/locale/none.c +++ b/locale/FreeBSD/none.c @@ -32,21 +32,22 @@ * LIABILITY, OR TORT (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/none.c,v 1.2.8.1 2001/03/05 10:25:03 obrien Exp $ */ #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.6 2002/10/16 11:37:38 tjr Exp $"); +#include #include #include #include #include -rune_t _none_sgetrune __P((const char *, size_t, char const **)); -int _none_sputrune __P((rune_t, char *, size_t, char **)); +rune_t _none_sgetrune(const char *, size_t, char const **); +int _none_sputrune(rune_t, char *, size_t, char **); int _none_init(rl) @@ -82,8 +83,14 @@ _none_sputrune(c, string, n, result) size_t n; { if (n >= 1) { - if (string) + if (string) { + if (c < 0 || c > UCHAR_MAX) { + if (result) + *result = NULL; + return (0); + } *string = c; + } if (result) *result = string + 1; } else if (result) diff --git a/locale/rune.3 b/locale/FreeBSD/rune.3 similarity index 90% rename from locale/rune.3 rename to locale/FreeBSD/rune.3 index 570e73d..2d5ddb7 100644 --- a/locale/rune.3 +++ b/locale/FreeBSD/rune.3 @@ -33,9 +33,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)rune.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/locale/rune.3,v 1.10.2.6 2001/12/14 18:33:54 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/rune.3,v 1.22 2002/12/19 09:40:22 ru Exp $ .\" -.Dd December 11, 1993 +.Dd October 6, 2002 .Dt RUNE 3 .Os .Sh NAME @@ -69,6 +69,25 @@ .Ft int .Fn fputrune "rune_t rune" "FILE *stream" .Sh DESCRIPTION +.Bf Em +The +.Bx 4.4 +.Dq rune +functions have been deprecated in favour of the +.Tn ISO +C99 extended multibyte and wide character facilities +and should not be used in new applications. +.Ef +Consider using +.Xr setlocale 3 , +.Xr mbrtowc 3 , +.Xr wcrtomb 3 , +.Xr fgetwc 3 , +.Xr ungetwc 3 , +and +.Xr fputwc 3 +instead. +.Pp The .Fn setrunelocale controls the type of encoding used to represent runes as multibyte strings @@ -215,18 +234,18 @@ The function returns one of the following values: .Bl -tag -width Er .It Er 0 +The .Fn setrunelocale +function was successful. -.It Bq Er EFAULT +.It Bq Er EINVAL +The .Fa locale -was -.Dv NULL . +name was incorrect. .It Bq Er ENOENT The locale could not be found. .It Bq Er EFTYPE The file found was not a valid file. -.It Bq Er EINVAL -The encoding indicated by the locale was unknown. .El .Pp The @@ -249,16 +268,8 @@ binary LC_CTYPE file for the locale .Xr mbrune 3 , .Xr setlocale 3 , .Xr euc 4 , -.Xr utf2 4 -.Sh NOTES -The ANSI C type -.Em wchar_t -is the same as -.Em rune_t . -.Em Rune_t -was chosen to accent the purposeful choice of not basing the -system with the ANSI C -primitives, which were, shall we say, less aesthetic. +.Xr utf2 4 , +.Xr utf8 5 .Sh HISTORY These functions first appeared in .Bx 4.4 . @@ -266,12 +277,7 @@ These functions first appeared in The .Fn setrunelocale function and the other non-ANSI rune functions were inspired by -.Sy "Plan 9 from Bell Labs" -as a much more sane alternative to the ANSI multibyte and -wide character support. +.Sy "Plan 9 from Bell Labs" . .\"They were conceived at the San Diego 1993 Summer USENIX conference by .\"Paul Borman of Krystal Technologies, Keith Bostic of CSRG and Andrew Hume .\"of Bell Labs. -.Pp -All of the ANSI multibyte and wide character -support functions are built using the rune functions. diff --git a/locale/rune.c b/locale/FreeBSD/rune.c similarity index 86% rename from locale/rune.c rename to locale/FreeBSD/rune.c index 5531c76..b67d9e9 100644 --- a/locale/rune.c +++ b/locale/FreeBSD/rune.c @@ -32,20 +32,24 @@ * LIABILITY, OR TORT (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/rune.c,v 1.5.8.1 2001/03/05 10:26:02 obrien Exp $ */ #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.10 2002/08/09 08:22:29 ache Exp $"); +#include "namespace.h" +#include +#include #include #include #include #include #include #include +#include "un-namespace.h" _RuneLocale * _Read_RuneMagi(fp) @@ -56,22 +60,33 @@ _Read_RuneMagi(fp) _RuneLocale *rl; _RuneEntry *rr; struct stat sb; - int x; + int x, saverr; - if (fstat(fileno(fp), &sb) < 0) - return(0); + if (_fstat(fileno(fp), &sb) < 0) + return (NULL); - if (sb.st_size < sizeof(_RuneLocale)) - return(0); + if (sb.st_size < sizeof(_RuneLocale)) { + errno = EFTYPE; + return (NULL); + } if ((data = malloc(sb.st_size)) == NULL) - return(0); + return (NULL); + errno = 0; rewind(fp); /* Someone might have read the magic number once already */ + if (errno) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } if (fread(data, sb.st_size, 1, fp) != 1) { + saverr = errno; free(data); - return(0); + errno = saverr; + return (NULL); } rl = (_RuneLocale *)data; @@ -81,7 +96,8 @@ _Read_RuneMagi(fp) if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } rl->invalid_rune = ntohl(rl->invalid_rune); @@ -100,21 +116,24 @@ _Read_RuneMagi(fp) rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges; if (rl->variable > lastp) { free(data); - return(0); + 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); - return(0); + 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); - return(0); + errno = EFTYPE; + return (NULL); } for (x = 0; x < rl->runetype_ext.nranges; ++x) { @@ -128,7 +147,8 @@ _Read_RuneMagi(fp) rl->variable = rr[x].types + len; if (rl->variable > lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } while (len-- > 0) rr[x].types[len] = ntohl(rr[x].types[len]); @@ -153,7 +173,8 @@ _Read_RuneMagi(fp) } if (((char *)rl->variable) + rl->variable_len > (char *)lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } /* @@ -171,5 +192,5 @@ _Read_RuneMagi(fp) if (!rl->mapupper_ext.nranges) rl->mapupper_ext.ranges = 0; - return(rl); + return (rl); } diff --git a/locale/FreeBSD/rune.c.patch b/locale/FreeBSD/rune.c.patch new file mode 100644 index 0000000..e2785e1 --- /dev/null +++ b/locale/FreeBSD/rune.c.patch @@ -0,0 +1,10 @@ +--- rune.c.orig Fri Aug 9 01:22:29 2002 ++++ rune.c Sat May 3 14:15:04 2003 +@@ -41,7 +41,6 @@ + __FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.10 2002/08/09 08:22:29 ache Exp $"); + + #include "namespace.h" +-#include + #include + #include + #include diff --git a/locale/runetype.c b/locale/FreeBSD/runetype.c similarity index 94% rename from locale/runetype.c rename to locale/FreeBSD/runetype.c index 9f5228c..e843637 100644 --- a/locale/runetype.c +++ b/locale/FreeBSD/runetype.c @@ -32,16 +32,17 @@ * LIABILITY, OR TORT (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/runetype.c,v 1.5.8.1 2000/06/04 21:47:39 ache Exp $ */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.8 2002/08/21 16:19:56 mike Exp $"); + #include #include unsigned long ___runetype(c) - _BSD_CT_RUNE_T_ c; + __ct_rune_t c; { int x; _RuneRange *rr = &_CurrentRuneLocale->runetype_ext; diff --git a/locale/FreeBSD/runetype.c.patch b/locale/FreeBSD/runetype.c.patch new file mode 100644 index 0000000..edccc90 --- /dev/null +++ b/locale/FreeBSD/runetype.c.patch @@ -0,0 +1,53 @@ +--- runetype.c.orig Tue May 20 15:21:44 2003 ++++ runetype.c Tue Jun 17 17:50:43 2003 +@@ -39,27 +39,39 @@ + + #include + #include ++#include ++ ++__private_extern__ int ++__compRuneEntry(const void *rune, const void *range) ++{ ++ __ct_rune_t c = *(__ct_rune_t *)rune; ++ _RuneEntry *re = (_RuneEntry *)range; ++ ++ if (c < re->min) ++ return(-1); ++ if (c > re->max) ++ return(1); ++ return(0); ++} + + unsigned long + ___runetype(c) + __ct_rune_t c; + { +- int x; + _RuneRange *rr = &_CurrentRuneLocale->runetype_ext; +- _RuneEntry *re = rr->ranges; ++ _RuneEntry *re; + + if (c < 0 || c == EOF) + return(0L); + +- for (x = 0; x < rr->nranges; ++x, ++re) { +- if (c < re->min) +- return(0L); +- if (c <= re->max) { +- if (re->types) +- return(re->types[c - re->min]); +- else +- return(re->map); +- } ++ re = (_RuneEntry *)bsearch(&c, rr->ranges, rr->nranges, ++ sizeof(_RuneEntry), __compRuneEntry); ++ ++ if (re) { ++ if (re->types) ++ return(re->types[c - re->min]); ++ else ++ return(re->map); + } + + return(0L); diff --git a/locale/setinvalidrune.c b/locale/FreeBSD/setinvalidrune.c similarity index 90% rename from locale/setinvalidrune.c rename to locale/FreeBSD/setinvalidrune.c index 45a2a47..67cd200 100644 --- a/locale/setinvalidrune.c +++ b/locale/FreeBSD/setinvalidrune.c @@ -34,8 +34,12 @@ * SUCH DAMAGE. */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/setinvalidrune.c,v 1.3 2002/09/24 09:25:37 tjr Exp $"); + #include +__warn_references(setinvalidrune, "warning: setinvalidrune() is deprecated. See setinvalidrune(3)."); void setinvalidrune(ir) rune_t ir; diff --git a/locale/setlocale.3 b/locale/FreeBSD/setlocale.3 similarity index 87% rename from locale/setlocale.3 rename to locale/FreeBSD/setlocale.3 index b0cdfb6..f34c970 100644 --- a/locale/setlocale.3 +++ b/locale/FreeBSD/setlocale.3 @@ -33,9 +33,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.15.2.5 2001/12/14 18:33:55 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.26 2003/03/20 08:13:34 ache Exp $ .\" -.Dd June 9, 1993 +.Dd October 5, 2002 .Dt SETLOCALE 3 .Os .Sh NAME @@ -163,6 +163,12 @@ struct lconv { 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 @@ -170,7 +176,8 @@ The individual fields have the following meanings: .Pp .Bl -tag -width mon_decimal_point .It Fa decimal_point -The decimal point character, except for currency values. +The decimal point character, except for currency values, +can't be the empty string. .It Fa thousands_sep The separator between groups of digits before the decimal point, except for currency values. @@ -249,6 +256,30 @@ Just after Like .Fa p_sign_posn but for negative currency values. +.It Fa int_p_cs_precedes +Same as +.Fa p_cs_precedes , +but for internationally formatted monetary quantities. +.It Fa int_n_cs_precedes +Same as +.Fa n_cs_precedes , +but for internationally formatted monetary quantities. +.It Fa int_p_sep_by_space +Same as +.Fa p_sep_by_space , +but for internationally formatted monetary quantities. +.It Fa int_n_sep_by_space +Same as +.Fa n_sep_by_space , +but for internationally formatted monetary quantities. +.It Fa int_p_sign_posn +Same as +.Fa p_sign_posn , +but for internationally formatted monetary quantities. +.It Fa int_n_sign_posn +Same as +.Fa n_sign_posn , +but for internationally formatted monetary quantities. .El .Pp Unless mentioned above, @@ -259,6 +290,12 @@ A .Dv CHAR_MAX result similarly denotes an unavailable value. .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 @@ -276,6 +313,8 @@ which may be altered by later calls to .Fn setlocale or .Fn localeconv . +.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 @@ -296,14 +335,15 @@ and the category .Xr strcoll 3 , .Xr strxfrm 3 , .Xr euc 4 , -.Xr utf2 4 +.Xr utf2 4 , +.Xr utf8 5 .Sh STANDARDS The .Fn setlocale and .Fn localeconv functions conform to -.St -isoC . +.St -isoC-99 . .Sh HISTORY The .Fn setlocale @@ -311,28 +351,3 @@ and .Fn localeconv functions first appeared in .Bx 4.4 . -.Sh BUGS -The current implementation supports only the -.Li "\&""C"" -and -.Li "\&""POSIX"" -locales for all but the -.Dv LC_COLLATE , -.Dv LC_CTYPE , -and -.Dv LC_TIME -categories. -.Pp -In spite of the gnarly currency support in -.Fn localeconv , -the standards don't include any functions -for generalized currency formatting. -.Pp -Use of -.Dv LC_MONETARY -could lead to misleading results until we have a real time currency -conversion function. -.Dv LC_NUMERIC -and -.Dv LC_TIME -are personal choices and should not be wrapped up with the other categories. diff --git a/locale/setlocale.c b/locale/FreeBSD/setlocale.c similarity index 61% rename from locale/setlocale.c rename to locale/FreeBSD/setlocale.c index 3ec6fca..3f59bea 100644 --- a/locale/setlocale.c +++ b/locale/FreeBSD/setlocale.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 1996 - 2002 FreeBSD Project * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -34,17 +35,15 @@ * SUCH DAMAGE. */ -#ifdef LIBC_RCS -static const char rcsid[] = - "$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.25.2.4 2001/03/05 13:08:42 ru Exp $"; -#endif - #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.41 2002/08/08 05:51:54 ache Exp $"); #include #include +#include #include #include #include @@ -52,7 +51,12 @@ static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93"; #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 "../stdtime/timelocal.h" /* for __time_load_locale() */ /* * Category names for getenv() @@ -64,7 +68,7 @@ static char *categories[_LC_LAST] = { "LC_MONETARY", "LC_NUMERIC", "LC_TIME", - "LC_MESSAGES" + "LC_MESSAGES", }; /* @@ -77,7 +81,7 @@ static char current_categories[_LC_LAST][ENCODING_LEN + 1] = { "C", "C", "C", - "C" + "C", }; /* @@ -88,24 +92,24 @@ static char saved_categories[_LC_LAST][ENCODING_LEN + 1]; static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)]; -static char *currentlocale __P((void)); -static char *loadlocale __P((int)); -static int stub_load_locale __P((const char *)); - -extern int __time_load_locale __P((const char *)); /* strftime.c */ +static char *currentlocale(void); +static int wrap_setrunelocale(const char *); +static char *loadlocale(int); char * setlocale(category, locale) int category; const char *locale; { - int i, j, len; + int i, j, len, saverr; char *env, *r; - if (category < LC_ALL || category >= _LC_LAST) + if (category < LC_ALL || category >= _LC_LAST) { + errno = EINVAL; return (NULL); + } - if (!locale) + if (locale == NULL) return (category != LC_ALL ? current_categories[category] : currentlocale()); @@ -121,68 +125,94 @@ setlocale(category, locale) if (!*locale) { env = getenv("LC_ALL"); - if (category != LC_ALL && (!env || !*env)) + if (category != LC_ALL && (env == NULL || !*env)) env = getenv(categories[category]); - if (!env || !*env) + if (env == NULL || !*env) env = getenv("LANG"); - if (!env || !*env || strchr(env, '/')) + if (env == NULL || !*env) env = "C"; - (void) strncpy(new_categories[category], env, ENCODING_LEN); - new_categories[category][ENCODING_LEN] = '\0'; + if (strlen(env) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[category], env); + if (category == LC_ALL) { for (i = 1; i < _LC_LAST; ++i) { - if (!(env = getenv(categories[i])) || !*env) + if ((env = getenv(categories[i])) == NULL || + !*env) env = new_categories[LC_ALL]; - (void)strncpy(new_categories[i], env, ENCODING_LEN); - new_categories[i][ENCODING_LEN] = '\0'; + else if (strlen(env) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[i], env); } } - } else if (category != LC_ALL) { - (void)strncpy(new_categories[category], locale, ENCODING_LEN); - new_categories[category][ENCODING_LEN] = '\0'; + } 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) { - for (i = 1; i < _LC_LAST; ++i) { - (void)strncpy(new_categories[i], locale, ENCODING_LEN); - new_categories[i][ENCODING_LEN] = '\0'; + 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]) + for (i = 1; r[1] == '/'; ++r) + ; + if (!r[1]) { + errno = EINVAL; return (NULL); /* Hmm, just slashes... */ + } do { - len = r - locale > ENCODING_LEN ? ENCODING_LEN : r - locale; - (void)strncpy(new_categories[i], locale, len); - new_categories[i][len] = '\0'; + 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++; locale = r; while (*locale == '/') - ++locale; - while (*++r && *r != '/'); + ++locale; + while (*++r && *r != '/') + ; } while (*locale); while (i < _LC_LAST) { (void)strcpy(new_categories[i], - new_categories[i-1]); + new_categories[i-1]); i++; } } } - if (category) + if (category != LC_ALL) return (loadlocale(category)); 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]); - /* XXX can fail too */ - (void)loadlocale(j); + saved_categories[j]); + if (loadlocale(j) == NULL) { + (void)strcpy(new_categories[j], "C"); + (void)loadlocale(j); + } } + errno = saverr; return (NULL); } } @@ -199,21 +229,41 @@ currentlocale() 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]); + (void)strcat(current_locale_string, "/"); + (void)strcat(current_locale_string, + current_categories[i]); } break; } return (current_locale_string); } +static int +wrap_setrunelocale(const char *locale) +{ + int ret = setrunelocale((char *)locale); + + if (ret != 0) { + errno = ret; + return (_LDP_ERROR); + } + return (_LDP_LOADED); +} + static char * loadlocale(category) int category; { - char *ret; char *new = new_categories[category]; char *old = current_categories[category]; + int (*func)(const char *); + + if ((new[0] == '.' && + (new[1] == '\0' || (new[1] == '.' && new[2] == '\0'))) || + strchr(new, '/') != NULL) { + errno = EINVAL; + return (NULL); + } if (_PathLocale == NULL) { char *p = getenv("PATH_LOCALE"); @@ -224,84 +274,51 @@ loadlocale(category) #endif ) { if (strlen(p) + 1/*"/"*/ + ENCODING_LEN + - 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX) + 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX) { + errno = ENAMETOOLONG; return (NULL); + } _PathLocale = strdup(p); - if (_PathLocale == NULL) + if (_PathLocale == NULL) { + errno = ENOMEM; return (NULL); + } } else _PathLocale = _PATH_LOCALE; } - if (strcmp(new, old) == 0) - return (old); - - if (category == LC_CTYPE) { - ret = setrunelocale(new) ? NULL : new; - if (!ret) - (void)setrunelocale(old); - else - (void)strcpy(old, new); - return (ret); - } - - if (category == LC_COLLATE) { - ret = (__collate_load_tables(new) < 0) ? NULL : new; - if (!ret) - (void)__collate_load_tables(old); - else - (void)strcpy(old, new); - return (ret); + 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 (category == LC_TIME) { - ret = (__time_load_locale(new) < 0) ? NULL : new; - if (!ret) - (void)__time_load_locale(old); - else - (void)strcpy(old, new); - return (ret); - } + if (strcmp(new, old) == 0) + return (old); - if (category == LC_MONETARY || - category == LC_MESSAGES || - category == LC_NUMERIC) { - ret = stub_load_locale(new) ? NULL : new; - if (!ret) - (void)stub_load_locale(old); - else - (void)strcpy(old, new); - return (ret); + if (func(new) != _LDP_ERROR) { + (void)strcpy(old, new); + return (old); } - /* Just in case...*/ return (NULL); } -static int -stub_load_locale(encoding) -const char *encoding; -{ - char name[PATH_MAX]; - struct stat st; - - if (!encoding) - return(1); - /* - * The "C" and "POSIX" locale are always here. - */ - if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) - return(0); - if (!_PathLocale) - return(1); - /* Range checking not needed, encoding has fixed size */ - strcpy(name, _PathLocale); - strcat(name, "/"); - strcat(name, encoding); -#if 0 - /* - * Some day we will actually look at this file. - */ -#endif - return (stat(name, &st) != 0 || !S_ISDIR(st.st_mode)); -} diff --git a/locale/FreeBSD/setlocale.c.patch b/locale/FreeBSD/setlocale.c.patch new file mode 100644 index 0000000..a051de4 --- /dev/null +++ b/locale/FreeBSD/setlocale.c.patch @@ -0,0 +1,11 @@ +--- setlocale.c.orig Wed Aug 7 22:51:54 2002 ++++ setlocale.c Sat May 3 14:15:25 2003 +@@ -56,7 +56,7 @@ + #include "lmessages.h" /* for __messages_load_locale() */ + #include "setlocale.h" + #include "ldpart.h" +-#include "../stdtime/timelocal.h" /* for __time_load_locale() */ ++#include "timelocal.h" /* for __time_load_locale() */ + + /* + * Category names for getenv() diff --git a/locale/setlocale.h b/locale/FreeBSD/setlocale.h similarity index 89% rename from locale/setlocale.h rename to locale/FreeBSD/setlocale.h index f3b2a22..3eb7698 100644 --- a/locale/setlocale.h +++ b/locale/FreeBSD/setlocale.h @@ -1,6 +1,4 @@ -#ifndef _SETLOCALE_H -#define _SETLOCALE_H -/* +/*- * Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia. * All rights reserved. * @@ -24,11 +22,16 @@ * LIABILITY, OR TORT (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.4 2001/12/20 18:28:52 phantom Exp $ */ +#ifndef _SETLOCALE_H_ +#define _SETLOCALE_H_ + #define ENCODING_LEN 31 #define CATEGORY_LEN 11 extern char *_PathLocale; -#endif /* SETLOCALE_H */ +#endif /* !_SETLOCALE_H_ */ diff --git a/locale/setrunelocale.c b/locale/FreeBSD/setrunelocale.c similarity index 55% rename from locale/setrunelocale.c rename to locale/FreeBSD/setrunelocale.c index 509fac2..3203742 100644 --- a/locale/setrunelocale.c +++ b/locale/FreeBSD/setrunelocale.c @@ -32,10 +32,11 @@ * LIABILITY, OR TORT (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/setrunelocale.c,v 1.14.6.1 2000/06/04 21:47:39 ache Exp $ */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.26 2002/10/10 22:56:18 tjr Exp $"); + #include #include #include @@ -45,32 +46,54 @@ #include #include "setlocale.h" -extern int _none_init __P((_RuneLocale *)); -extern int _UTF2_init __P((_RuneLocale *)); -extern int _EUC_init __P((_RuneLocale *)); -extern int _BIG5_init __P((_RuneLocale *)); -extern int _MSKanji_init __P((_RuneLocale *)); -extern _RuneLocale *_Read_RuneMagi __P((FILE *)); +extern int _none_init(_RuneLocale *); +extern int _UTF2_init(_RuneLocale *); +extern int _UTF8_init(_RuneLocale *); +extern int _EUC_init(_RuneLocale *); +extern int _BIG5_init(_RuneLocale *); +extern int _MSKanji_init(_RuneLocale *); +extern _RuneLocale *_Read_RuneMagi(FILE *); int -setrunelocale(encoding) - char *encoding; +setrunelocale(char *encoding) { FILE *fp; char name[PATH_MAX]; _RuneLocale *rl; + int saverr, ret; + static char ctype_encoding[ENCODING_LEN + 1]; + static _RuneLocale *CachedRuneLocale; + static int Cached__mb_cur_max; - if (!encoding || strlen(encoding) > ENCODING_LEN) - return(EFAULT); + if (!encoding || !*encoding || strlen(encoding) > ENCODING_LEN || + (encoding[0] == '.' && + (encoding[1] == '\0' || + (encoding[1] == '.' && encoding[2] == '\0'))) || + strchr(encoding, '/') != NULL) + return (EINVAL); /* * The "C" and "POSIX" locale are always here. */ - if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) { + if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { _CurrentRuneLocale = &_DefaultRuneLocale; - return(0); + __mb_cur_max = 1; + return (0); } + /* + * If the locale name is the same as our cache, use the cache. + */ + if (CachedRuneLocale != NULL && + strcmp(encoding, ctype_encoding) == 0) { + _CurrentRuneLocale = CachedRuneLocale; + __mb_cur_max = Cached__mb_cur_max; + return (0); + } + + /* + * Slurp the locale file into the cache. + */ if (_PathLocale == NULL) { char *p = getenv("PATH_LOCALE"); @@ -81,10 +104,10 @@ setrunelocale(encoding) ) { if (strlen(p) + 1/*"/"*/ + ENCODING_LEN + 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX) - return(EFAULT); + return (ENAMETOOLONG); _PathLocale = strdup(p); if (_PathLocale == NULL) - return (errno); + return (errno == 0 ? ENOMEM : errno); } else _PathLocale = _PATH_LOCALE; } @@ -95,27 +118,42 @@ setrunelocale(encoding) (void) strcat(name, "/LC_CTYPE"); if ((fp = fopen(name, "r")) == NULL) - return(ENOENT); + return (errno == 0 ? ENOENT : errno); - if ((rl = _Read_RuneMagi(fp)) == 0) { - fclose(fp); - return(EFTYPE); + if ((rl = _Read_RuneMagi(fp)) == NULL) { + saverr = (errno == 0 ? EFTYPE : errno); + (void)fclose(fp); + return (saverr); } - fclose(fp); + (void)fclose(fp); - if (!rl->encoding[0]) - return(EINVAL); - else if (!strcmp(rl->encoding, "NONE")) - return(_none_init(rl)); - else if (!strcmp(rl->encoding, "UTF2")) - return(_UTF2_init(rl)); - else if (!strcmp(rl->encoding, "EUC")) - return(_EUC_init(rl)); - else if (!strcmp(rl->encoding, "BIG5")) - return(_BIG5_init(rl)); - else if (!strcmp(rl->encoding, "MSKanji")) - return(_MSKanji_init(rl)); + if (strcmp(rl->encoding, "NONE") == 0) + ret = _none_init(rl); + else if (strcmp(rl->encoding, "UTF2") == 0) + ret = _UTF2_init(rl); + else if (strcmp(rl->encoding, "UTF-8") == 0) + ret = _UTF8_init(rl); + else if (strcmp(rl->encoding, "EUC") == 0) + ret = _EUC_init(rl); + else if (strcmp(rl->encoding, "BIG5") == 0) + ret = _BIG5_init(rl); + else if (strcmp(rl->encoding, "MSKanji") == 0) + ret = _MSKanji_init(rl); else - return(EINVAL); + ret = EFTYPE; + if (ret == 0) { + if (CachedRuneLocale != NULL) { + /* See euc.c */ + if (strcmp(CachedRuneLocale->encoding, "EUC") == 0) + free(CachedRuneLocale->variable); + free(CachedRuneLocale); + } + CachedRuneLocale = _CurrentRuneLocale; + Cached__mb_cur_max = __mb_cur_max; + (void)strcpy(ctype_encoding, encoding); + } else + free(rl); + + return (ret); } diff --git a/locale/table.c b/locale/FreeBSD/table.c similarity index 97% rename from locale/table.c rename to locale/FreeBSD/table.c index 4771c56..6fb21c6 100644 --- a/locale/table.c +++ b/locale/FreeBSD/table.c @@ -32,20 +32,20 @@ * LIABILITY, OR TORT (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/table.c,v 1.13.2.1 2000/06/04 21:47:39 ache Exp $ */ #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.16 2002/03/22 21:52:18 obrien Exp $"); #include #include -extern rune_t _none_sgetrune __P((const char *, size_t, char const **)); -extern int _none_sputrune __P((rune_t, char *, size_t, char **)); -extern int _none_init __P((char *, char **)); +extern rune_t _none_sgetrune(const char *, size_t, char const **); +extern int _none_sputrune(rune_t, char *, size_t, char **); +extern int _none_init(char *, char **); _RuneLocale _DefaultRuneLocale = { _RUNE_MAGIC_1, diff --git a/locale/toascii.3 b/locale/FreeBSD/toascii.3 similarity index 96% rename from locale/toascii.3 rename to locale/FreeBSD/toascii.3 index 82099ef..b1a2425 100644 --- a/locale/toascii.3 +++ b/locale/FreeBSD/toascii.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)toascii.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/toascii.3,v 1.4.2.2 2001/12/14 18:33:55 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/toascii.3,v 1.7 2002/01/09 13:43:31 nik Exp $ .\" .Dd June 4, 1993 .Dt TOASCII 3 @@ -54,6 +54,7 @@ The .Fn toascii function always returns a valid ASCII character. .Sh SEE ALSO +.Xr digittoint 3 , .Xr isalnum 3 , .Xr isalpha 3 , .Xr isascii 3 , diff --git a/locale/tolower.3 b/locale/FreeBSD/tolower.3 similarity index 87% rename from locale/tolower.3 rename to locale/FreeBSD/tolower.3 index 761948c..bb2c801 100644 --- a/locale/tolower.3 +++ b/locale/FreeBSD/tolower.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/tolower.3,v 1.6.2.4 2001/12/14 18:33:55 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/tolower.3,v 1.15 2002/10/03 11:14:00 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 3, 2002 .Dt TOLOWER 3 .Os .Sh NAME @@ -67,24 +67,22 @@ 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 +Although +.Fn tolower +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn towlower +function should be used instead for maximum portability. .Sh SEE ALSO -.Xr isalnum 3 , -.Xr isalpha 3 , -.Xr isascii 3 , -.Xr iscntrl 3 , -.Xr isdigit 3 , -.Xr isgraph 3 , +.Xr ctype 3 , .Xr islower 3 , -.Xr isprint 3 , -.Xr ispunct 3 , -.Xr isspace 3 , -.Xr isupper 3 , -.Xr isxdigit 3 , .Xr multibyte 3 , -.Xr stdio 3 , -.Xr toascii 3 , -.Xr toupper 3 , -.Xr ascii 7 +.Xr towlower 3 .Sh STANDARDS The .Fn tolower diff --git a/locale/tolower.c b/locale/FreeBSD/tolower.c similarity index 94% rename from locale/tolower.c rename to locale/FreeBSD/tolower.c index 3ed1840..bac8445 100644 --- a/locale/tolower.c +++ b/locale/FreeBSD/tolower.c @@ -32,16 +32,17 @@ * LIABILITY, OR TORT (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/tolower.c,v 1.5.8.1 2000/06/04 21:47:39 ache Exp $ */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.8 2002/08/21 16:19:56 mike Exp $"); + #include #include -_BSD_CT_RUNE_T_ +__ct_rune_t ___tolower(c) - _BSD_CT_RUNE_T_ c; + __ct_rune_t c; { int x; _RuneRange *rr = &_CurrentRuneLocale->maplower_ext; diff --git a/locale/FreeBSD/tolower.c.patch b/locale/FreeBSD/tolower.c.patch new file mode 100644 index 0000000..6de7d33 --- /dev/null +++ b/locale/FreeBSD/tolower.c.patch @@ -0,0 +1,37 @@ +--- tolower.c.orig Tue May 20 15:21:44 2003 ++++ tolower.c Tue Jun 17 17:45:56 2003 +@@ -39,6 +39,10 @@ + + #include + #include ++#include ++ ++__private_extern__ int ++__compRuneEntry(const void *, const void *); // from runetype.c + + __ct_rune_t + ___tolower(c) +@@ -46,17 +50,16 @@ + { + int x; + _RuneRange *rr = &_CurrentRuneLocale->maplower_ext; +- _RuneEntry *re = rr->ranges; ++ _RuneEntry *re; + + if (c < 0 || c == EOF) + return(c); + +- for (x = 0; x < rr->nranges; ++x, ++re) { +- if (c < re->min) +- return(c); +- if (c <= re->max) +- return(re->map + c - re->min); +- } ++ re = (_RuneEntry *)bsearch(&c, rr->ranges, rr->nranges, ++ sizeof(_RuneEntry), __compRuneEntry); ++ ++ if (re) ++ return(re->map + c - re->min); + + return(c); + } diff --git a/locale/toupper.3 b/locale/FreeBSD/toupper.3 similarity index 87% rename from locale/toupper.3 rename to locale/FreeBSD/toupper.3 index e4edd22..f0fddf9 100644 --- a/locale/toupper.3 +++ b/locale/FreeBSD/toupper.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/toupper.3,v 1.5.2.5 2001/12/14 18:33:55 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/toupper.3,v 1.15 2002/10/03 11:14:00 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 3, 2002 .Dt TOUPPER 3 .Os .Sh NAME @@ -67,24 +67,22 @@ 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 +Although +.Fn toupper +accepts arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets, +this is a +.Bx 4.4 +extension and the +.Fn towupper +function should be used instead for maximum portability. .Sh SEE ALSO -.Xr isalnum 3 , -.Xr isalpha 3 , -.Xr isascii 3 , -.Xr iscntrl 3 , -.Xr isdigit 3 , -.Xr isgraph 3 , -.Xr islower 3 , -.Xr isprint 3 , -.Xr ispunct 3 , -.Xr isspace 3 , +.Xr ctype 3 , .Xr isupper 3 , -.Xr isxdigit 3 , .Xr multibyte 3 , -.Xr stdio 3 , -.Xr toascii 3 , -.Xr tolower 3 , -.Xr ascii 7 +.Xr towupper 3 .Sh STANDARDS The .Fn toupper diff --git a/locale/toupper.c b/locale/FreeBSD/toupper.c similarity index 94% rename from locale/toupper.c rename to locale/FreeBSD/toupper.c index 9fbe9d7..44d6fde 100644 --- a/locale/toupper.c +++ b/locale/FreeBSD/toupper.c @@ -32,16 +32,17 @@ * LIABILITY, OR TORT (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/toupper.c,v 1.5.8.1 2000/06/04 21:47:39 ache Exp $ */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.8 2002/08/21 16:19:56 mike Exp $"); + #include #include -_BSD_CT_RUNE_T_ +__ct_rune_t ___toupper(c) - _BSD_CT_RUNE_T_ c; + __ct_rune_t c; { int x; _RuneRange *rr = &_CurrentRuneLocale->mapupper_ext; diff --git a/locale/FreeBSD/toupper.c.patch b/locale/FreeBSD/toupper.c.patch new file mode 100644 index 0000000..2f54eeb --- /dev/null +++ b/locale/FreeBSD/toupper.c.patch @@ -0,0 +1,37 @@ +--- toupper.c.orig Tue May 20 15:21:44 2003 ++++ toupper.c Tue Jun 17 17:49:05 2003 +@@ -39,6 +39,10 @@ + + #include + #include ++#include ++ ++__private_extern__ int ++__compRuneEntry(const void *, const void *); // from runetype.c + + __ct_rune_t + ___toupper(c) +@@ -46,17 +50,16 @@ + { + int x; + _RuneRange *rr = &_CurrentRuneLocale->mapupper_ext; +- _RuneEntry *re = rr->ranges; ++ _RuneEntry *re; + + if (c < 0 || c == EOF) + return(c); + +- for (x = 0; x < rr->nranges; ++x, ++re) { +- if (c < re->min) +- return(c); +- if (c <= re->max) +- return(re->map + c - re->min); +- } ++ re = (_RuneEntry *)bsearch(&c, rr->ranges, rr->nranges, ++ sizeof(_RuneEntry), __compRuneEntry); ++ ++ if (re) ++ return(re->map + c - re->min); + + return(c); + } diff --git a/gen/modf.3 b/locale/FreeBSD/towlower.3 similarity index 75% rename from gen/modf.3 rename to locale/FreeBSD/towlower.3 index 3971000..6bdd3c8 100644 --- a/gen/modf.3 +++ b/locale/FreeBSD/towlower.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1991, 1993 +.\" 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 @@ -33,43 +33,38 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)modf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/modf.3,v 1.7 2001/10/01 16:08:51 ru Exp $ +.\" @(#)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 June 4, 1993 -.Dt MODF 3 +.Dd October 3, 2002 +.Dt TOWLOWER 3 .Os .Sh NAME -.Nm modf -.Nd extract signed integral and fractional values from floating-point number +.Nm towlower +.Nd "upper case to lower case letter conversion (wide character version)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In math.h -.Ft double -.Fn modf "double value" "double *iptr" +.In wctype.h +.Ft wint_t +.Fn towlower "wint_t wc" .Sh DESCRIPTION The -.Fn modf -function breaks the argument -.Fa value -into integral and fractional parts, each of which has the -same sign as the argument. -It stores the integral part as a -.Em double -in the object pointed to by -.Fa iptr . +.Fn towlower +function converts an upper-case letter to the corresponding lower-case +letter. .Sh RETURN VALUES -The -.Fn modf -function returns the signed fractional part of -.Fa value . +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 frexp 3 , -.Xr ldexp 3 , -.Xr math 3 +.Xr iswlower 3 , +.Xr tolower 3 , +.Xr towupper 3 , +.Xr wctrans 3 .Sh STANDARDS The -.Fn modf +.Fn towlower function conforms to -.St -isoC . +.St -isoC-99 . diff --git a/gen/ldexp.3 b/locale/FreeBSD/towupper.3 similarity index 75% rename from gen/ldexp.3 rename to locale/FreeBSD/towupper.3 index 88c0d2f..c771998 100644 --- a/gen/ldexp.3 +++ b/locale/FreeBSD/towupper.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1991, 1993 +.\" 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 @@ -33,48 +33,38 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)ldexp.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/gen/ldexp.3,v 1.8 2001/10/01 16:08:51 ru Exp $ +.\" @(#)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 April 19, 1994 -.Dt LDEXP 3 +.Dd October 3, 2002 +.Dt TOWUPPER 3 .Os .Sh NAME -.Nm ldexp -.Nd multiply floating-point number by integral power of 2 +.Nm towupper +.Nd "lower case to upper case letter conversion (wide character version)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In math.h -.Ft double -.Fn ldexp "double x" "int exp" +.In wctype.h +.Ft wint_t +.Fn towupper "wint_t wc" .Sh DESCRIPTION The -.Fn ldexp -function multiplies a floating-point number by an integral -power of 2. +.Fn towupper +function converts a lower-case letter to the corresponding +upper-case letter. .Sh RETURN VALUES -The -.Fn ldexp -function returns the value of -.Fa x -times 2 raised to the power -.Fa exp . -.Pp -If the resultant value would cause an overflow, -the global variable -.Va errno -is set to -.Er ERANGE -and the value -.Dv HUGE -is returned. +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 frexp 3 , -.Xr math 3 , -.Xr modf 3 +.Xr iswupper 3 , +.Xr toupper 3 , +.Xr towlower 3 , +.Xr wctrans 3 .Sh STANDARDS The -.Fn ldexp +.Fn towupper function conforms to -.St -isoC . +.St -isoC-99 . diff --git a/locale/utf2.4 b/locale/FreeBSD/utf2.4 similarity index 93% rename from locale/utf2.4 rename to locale/FreeBSD/utf2.4 index 3b81b9c..b581870 100644 --- a/locale/utf2.4 +++ b/locale/FreeBSD/utf2.4 @@ -33,9 +33,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)utf2.4 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/locale/utf2.4,v 1.8.2.1 2001/03/06 16:45:58 ru Exp $ +.\" $FreeBSD: src/lib/libc/locale/utf2.4,v 1.10 2002/10/10 22:56:18 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd October 11, 2002 .Dt UTF2 4 .Os .Sh NAME @@ -45,6 +45,11 @@ .Nm ENCODING .Qq UTF2 .Sh DESCRIPTION +.Bf Em +The UTF2 encoding has been deprecated in favour of UTF-8. +.Ef +New applications should not use UTF2. +.Pp The .Nm UTF2 encoding is based on a proposed X-Open multibyte @@ -85,4 +90,5 @@ which provides for the entire proposed ISO-10646 31 bit standard are currently not implemented. .Sh "SEE ALSO" .Xr mklocale 1 , -.Xr setlocale 3 +.Xr setlocale 3 , +.Xr utf8 5 diff --git a/locale/utf2.c b/locale/FreeBSD/utf2.c similarity index 94% rename from locale/utf2.c rename to locale/FreeBSD/utf2.c index 5219434..22a6ba4 100644 --- a/locale/utf2.c +++ b/locale/FreeBSD/utf2.c @@ -32,21 +32,21 @@ * LIABILITY, OR TORT (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/utf2.c,v 1.3.2.2 2001/03/05 10:27:18 obrien Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)utf2.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/utf2.c,v 1.7 2002/03/22 21:52:18 obrien Exp $"); #include #include #include #include -rune_t _UTF2_sgetrune __P((const char *, size_t, char const **)); -int _UTF2_sputrune __P((rune_t, char *, size_t, char **)); +rune_t _UTF2_sgetrune(const char *, size_t, char const **); +int _UTF2_sputrune(rune_t, char *, size_t, char **); static int _utf_count[16] = { 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/locale/FreeBSD/utf8.5 b/locale/FreeBSD/utf8.5 new file mode 100644 index 0000000..9b486eb --- /dev/null +++ b/locale/FreeBSD/utf8.5 @@ -0,0 +1,131 @@ +.\" 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. +.\" +.\" @(#)utf2.4 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/locale/utf8.5,v 1.3 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd October 30, 2002 +.Dt UTF8 5 +.Os +.Sh NAME +.Nm utf8 +.Nd "UTF-8, a transformation format of ISO 10646" +.Sh SYNOPSIS +.Nm ENCODING +.Qq UTF-8 +.Sh DESCRIPTION +The +.Nm UTF-8 +encoding represents UCS-4 characters as a sequence of octets, using +between 1 and 6 for each character. +It is backwards compatible with +.Tn ASCII , +so 0x00-0x7f refer to the +.Tn ASCII +character set. +The multibyte encoding of +.No non- Ns Tn ASCII +characters +consist entirely of bytes whose high order bit is set. +The actual +encoding is represented by the following table: +.Bd -literal +[0x00000000 - 0x0000007f] [00000000.0bbbbbbb] -> 0bbbbbbb +[0x00000080 - 0x000007ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb +[0x00000800 - 0x0000ffff] [bbbbbbbb.bbbbbbbb] -> + 1110bbbb, 10bbbbbb, 10bbbbbb +[0x00010000 - 0x001fffff] [00000000.000bbbbb.bbbbbbbb.bbbbbbbb] -> + 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb +[0x00200000 - 0x03ffffff] [000000bb.bbbbbbbb.bbbbbbbb.bbbbbbbb] -> + 111110bb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb +[0x04000000 - 0x7fffffff] [0bbbbbbb.bbbbbbbb.bbbbbbbb.bbbbbbbb] -> + 1111110b, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb +.Ed +.Pp +If more than a single representation of a value exists (for example, +0x00; 0xC0 0x80; 0xE0 0x80 0x80) the shortest representation is always +used. +Longer ones are detected as an error as they pose a potential +security risk, and destroy the 1:1 character:octet sequence mapping. +.Sh COMPATIBILITY +The +.Nm +encoding supersedes the +.Xr utf2 4 +encoding. +The only differences between the two are that +.Nm +handles the full 31-bit character set of +.Tn ISO +10646 +whereas +.Xr utf2 4 +is limited to a 16-bit character set, +and that +.Xr utf2 4 +accepts redundant, +.No non- Ns Dq "shortest form" +representations of characters. +.Sh SEE ALSO +.Xr euc 4 , +.Xr utf2 4 +.Rs +.%A "Rob Pike" +.%A "Ken Thompson" +.%T "Hello World" +.%J "Proceedings of the Winter 1993 USENIX Technical Conference" +.%Q "USENIX Association" +.%D "January 1993" +.Re +.Rs +.%A "F. Yergeau" +.%T "UTF-8, a transformation format of ISO 10646" +.%O "RFC 2279" +.%D "January 1998" +.Re +.Rs +.%Q "The Unicode Consortium" +.%T "The Unicode Standard, Version 3.0" +.%D "2000" +.%O "as amended by the Unicode Standard Annex #27: Unicode 3.1 and by the Unicode Standard Annex #28: Unicode 3.2" +.Re +.Sh STANDARDS +The +.Nm +encoding is compatible with RFC 2279 and Unicode 3.2. +.Sh BUGS +Byte order marker (BOM) characters are neither added nor removed +from UTF-8-encoded wide character +.Xr stdio 3 +streams. diff --git a/locale/FreeBSD/utf8.c b/locale/FreeBSD/utf8.c new file mode 100644 index 0000000..95ddce9 --- /dev/null +++ b/locale/FreeBSD/utf8.c @@ -0,0 +1,204 @@ +/*- + * 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/utf8.c,v 1.2 2003/02/18 13:39:51 nectar Exp $"); + +#include +#include +#include +#include + +rune_t _UTF8_sgetrune(const char *, size_t, char const **); +int _UTF8_sputrune(rune_t, char *, size_t, char **); + +int +_UTF8_init(_RuneLocale *rl) +{ + + rl->sgetrune = _UTF8_sgetrune; + rl->sputrune = _UTF8_sputrune; + _CurrentRuneLocale = rl; + __mb_cur_max = 6; + + return (0); +} + +rune_t +_UTF8_sgetrune(const char *string, size_t n, const char **result) +{ + int ch, len, mask; + rune_t lbound, wch; + + if (n < 1) { + if (result != NULL) + *result = string; + return (_INVALID_RUNE); + } + + /* + * 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 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)*string; + if ((ch & 0x80) == 0) { + mask = 0x7f; + len = 1; + lbound = 0; + } else if ((ch & 0xe0) == 0xc0) { + mask = 0x1f; + len = 2; + lbound = 0x80; + } else if ((ch & 0xf0) == 0xe0) { + mask = 0x0f; + len = 3; + lbound = 0x800; + } else if ((ch & 0xf8) == 0xf0) { + mask = 0x07; + len = 4; + lbound = 0x10000; + } else if ((ch & 0xfc) == 0xf8) { + mask = 0x03; + len = 5; + lbound = 0x200000; + } else if ((ch & 0xfc) == 0xfc) { + mask = 0x01; + len = 6; + lbound = 0x4000000; + } else { + /* + * Malformed input; input is not UTF-8. + */ + if (result != NULL) + *result = string + 1; + return (_INVALID_RUNE); + } + + if (n < len) { + /* + * Truncated or partial input. + */ + if (result != NULL) + *result = string; + return (_INVALID_RUNE); + } + + /* + * Decode the octet sequence representing the character in chunks + * of 6 bits, most significant first. + */ + wch = (unsigned char)*string++ & mask; + while (--len != 0) { + if ((*string & 0xc0) != 0x80) { + /* + * Malformed input; bad characters in the middle + * of a character. + */ + wch = _INVALID_RUNE; + if (result != NULL) + *result = string + 1; + return (_INVALID_RUNE); + } + wch <<= 6; + wch |= *string++ & 0x3f; + } + if (wch != _INVALID_RUNE && wch < lbound) + /* + * Malformed input; redundant encoding. + */ + wch = _INVALID_RUNE; + if (result != NULL) + *result = string; + return (wch); +} + +int +_UTF8_sputrune(rune_t c, char *string, size_t n, char **result) +{ + unsigned char lead; + int i, len; + + /* + * 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 ((c & ~0x7f) == 0) { + lead = 0; + len = 1; + } else if ((c & ~0x7ff) == 0) { + lead = 0xc0; + len = 2; + } else if ((c & ~0xffff) == 0) { + lead = 0xe0; + len = 3; + } else if ((c & ~0x1fffff) == 0) { + lead = 0xf0; + len = 4; + } else if ((c & ~0x3ffffff) == 0) { + lead = 0xf8; + len = 5; + } else if ((c & ~0x7fffffff) == 0) { + lead = 0xfc; + len = 6; + } else { + /* + * Wide character code is out of range. + */ + if (result != NULL) + *result = NULL; + return (0); + } + + if (n < len) { + if (result != NULL) + *result = NULL; + } else { + /* + * 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--) { + string[i] = (c & 0x3f) | 0x80; + c >>= 6; + } + *string = (c & 0xff) | lead; + if (result != NULL) + *result = string + len; + } + + return (len); +} diff --git a/locale/FreeBSD/utf8.c.patch b/locale/FreeBSD/utf8.c.patch new file mode 100644 index 0000000..dadd310 --- /dev/null +++ b/locale/FreeBSD/utf8.c.patch @@ -0,0 +1,64 @@ +--- utf8.c.orig Tue May 20 15:21:44 2003 ++++ utf8.c Wed Jun 18 12:07:28 2003 +@@ -53,11 +53,10 @@ + int ch, len, mask; + rune_t lbound, wch; + +- if (n < 1) { +- if (result != NULL) +- *result = string; ++ if (result != NULL) ++ *result = string; ++ if (n < 1) + return (_INVALID_RUNE); +- } + + /* + * Determine the number of octets that make up this character from +@@ -100,18 +99,15 @@ + * Malformed input; input is not UTF-8. + */ + if (result != NULL) +- *result = string + 1; ++ (*result)++; + return (_INVALID_RUNE); + } + +- if (n < len) { ++ if (n < len) + /* + * Truncated or partial input. + */ +- if (result != NULL) +- *result = string; + return (_INVALID_RUNE); +- } + + /* + * Decode the octet sequence representing the character in chunks +@@ -124,19 +120,21 @@ + * Malformed input; bad characters in the middle + * of a character. + */ +- wch = _INVALID_RUNE; + if (result != NULL) +- *result = string + 1; ++ (*result)++; + return (_INVALID_RUNE); + } + wch <<= 6; + wch |= *string++ & 0x3f; + } +- if (wch != _INVALID_RUNE && wch < lbound) ++ if (wch < lbound) { + /* + * Malformed input; redundant encoding. + */ +- wch = _INVALID_RUNE; ++ if (result != NULL) ++ (*result)++; ++ return (_INVALID_RUNE); ++ } + if (result != NULL) + *result = string; + return (wch); diff --git a/locale/FreeBSD/wcrtomb.3 b/locale/FreeBSD/wcrtomb.3 new file mode 100644 index 0000000..458a881 --- /dev/null +++ b/locale/FreeBSD/wcrtomb.3 @@ -0,0 +1,105 @@ +.\" 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/wcrtomb.3,v 1.3 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd August 15, 2002 +.Dt WCRTOMB 3 +.Os +.Sh NAME +.Nm wcrtomb +.Nd "convert a wide-character code to a character (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fn wcrtomb "char * restrict s" "wchar_t wc" "mbstate_t * restrict ps" +.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 , +storing a maximum of +.Dv MB_CUR_MAX +bytes. +.Pp +If +.Fa s +is +.Dv NULL , +.Fn wcrtomb +behaves as if +.Fa s +pointed to an internal buffer and +.Fa wc +was 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. +.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 EINVAL +.\"Invalid argument. +.It Bq Er EILSEQ +An invalid wide character code was specified. +.El +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr setlocale 3 , +.Xr wctomb 3 +.Sh STANDARDS +The +.Fn wcrtomb +function conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation does not support shift states. diff --git a/locale/FreeBSD/wcrtomb.c b/locale/FreeBSD/wcrtomb.c new file mode 100644 index 0000000..faf2f09 --- /dev/null +++ b/locale/FreeBSD/wcrtomb.c @@ -0,0 +1,52 @@ +/*- + * 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/wcrtomb.c,v 1.4 2003/04/10 09:20:38 tjr Exp $"); + +#include +#include +#include +#include +#include + +size_t +wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps __unused) +{ + char *e; + char buf[MB_LEN_MAX]; + + if (s == NULL) { + s = buf; + wc = L'\0'; + } + sputrune(wc, s, MB_CUR_MAX, &e); + if (e == NULL) { + errno = EILSEQ; + return ((size_t)-1); + } + return ((size_t)(e - s)); +} diff --git a/locale/FreeBSD/wcsftime.3 b/locale/FreeBSD/wcsftime.3 new file mode 100644 index 0000000..5f29f39 --- /dev/null +++ b/locale/FreeBSD/wcsftime.3 @@ -0,0 +1,66 @@ +.\" 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 +.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" "size_t maxsize" +.Fa "const wchar_t * restrict format" "const struct tm * restrict timeptr" +.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. +.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 +.Sh STANDARDS +The +.Fn wcsftime +function conforms to +.St -isoC-99 . diff --git a/locale/FreeBSD/wcsftime.c b/locale/FreeBSD/wcsftime.c new file mode 100644 index 0000000..21ec1e9 --- /dev/null +++ b/locale/FreeBSD/wcsftime.c @@ -0,0 +1,105 @@ +/*- + * 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.2 2002/09/15 08:06:17 tjr Exp $"); + +#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(wchar_t * __restrict wcs, size_t maxsize, + const wchar_t * __restrict format, const struct tm * __restrict timeptr) +{ + static const mbstate_t initial; + mbstate_t state; + char *dst, *dstp, *sformat; + size_t n, sflen; + int sverrno; + + sformat = dst = NULL; + + /* + * Convert the supplied format string to a multibyte representation + * for strftime(), which only handles single-byte characters. + */ + state = initial; + sflen = wcsrtombs(NULL, &format, 0, &state); + if (sflen == (size_t)-1) + goto error; + if ((sformat = malloc(sflen + 1)) == NULL) + goto error; + state = initial; + wcsrtombs(sformat, &format, sflen + 1, &state); + + /* + * 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 <= maxsize) { + /* maxsize is prepostorously large - avoid int. overflow. */ + errno = EINVAL; + goto error; + } + if ((dst = malloc(maxsize * MB_CUR_MAX)) == NULL) + goto error; + if (strftime(dst, maxsize, sformat, timeptr) == 0) + goto error; + state = initial; + dstp = dst; + n = mbsrtowcs(wcs, (const char **)&dstp, maxsize, &state); + 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); +} diff --git a/locale/FreeBSD/wcsrtombs.3 b/locale/FreeBSD/wcsrtombs.3 new file mode 100644 index 0000000..eb77a5d --- /dev/null +++ b/locale/FreeBSD/wcsrtombs.3 @@ -0,0 +1,110 @@ +.\" 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/wcsrtombs.3,v 1.3 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd August 16, 2002 +.Dt WCSRTOMBS 3 +.Os +.Sh NAME +.Nm wcsrtombs +.Nd "convert a wide-character string to a character string (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcsrtombs +.Fa "char * restrict dst" "const wchar_t ** restrict src" +.Fa "size_t len" "mbstate_t * restrict ps" +.Fc +.Sh DESCRIPTION +The +.Fn wcsrtombs +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 +.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. +.Sh RETURN VALUES +The +.Fn wcsrtombs +function returns the number of bytes stored in +the array pointed to by +.Fa dst +(not including any terminating null), if successful, otherwise it returns +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn wcsrtombs +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character was encountered. +.El +.Sh SEE ALSO +.Xr mbsrtowcs 3 , +.Xr wcrtomb 3 , +.Xr wcstombs 3 +.Sh STANDARDS +The +.Fn wcsrtombs +function conforms to +.St -isoC-99 . +.Sh BUGS +The current implementation does not support shift states. diff --git a/locale/FreeBSD/wcsrtombs.c b/locale/FreeBSD/wcsrtombs.c new file mode 100644 index 0000000..70e0f5f --- /dev/null +++ b/locale/FreeBSD/wcsrtombs.c @@ -0,0 +1,90 @@ +/*- + * 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/wcsrtombs.c,v 1.2 2002/09/06 11:23:45 tjr Exp $"); + +#include +#include +#include +#include +#include + +size_t +wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, + mbstate_t * __restrict ps __unused) +{ + char buf[MB_LEN_MAX]; + const wchar_t *s; + size_t nbytes; + int nb; + + s = *src; + nbytes = 0; + + if (dst == NULL) { + for (;;) { + if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) + /* Invalid character - wcrtomb() sets errno. */ + return ((size_t)-1); + else if (*s == L'\0') + return (nbytes + nb - 1); + s++; + nbytes += nb; + } + /*NOTREACHED*/ + } + + while (len > 0) { + if (len > (size_t)MB_CUR_MAX) { + /* Enough space to translate in-place. */ + if ((nb = (int)wcrtomb(dst, *s, NULL)) < 0) { + *src = s; + return ((size_t)-1); + } + } else { + /* May not be enough space; use temp. buffer. */ + if ((nb = (int)wcrtomb(buf, *s, NULL)) < 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/FreeBSD/wcstod.3 b/locale/FreeBSD/wcstod.3 new file mode 100644 index 0000000..25a8fcd --- /dev/null +++ b/locale/FreeBSD/wcstod.3 @@ -0,0 +1,70 @@ +.\" 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.3 2003/03/13 06:29:53 tjr Exp $ +.\" +.Dd February 22, 2003 +.Dt WCSTOD 3 +.Os +.Sh NAME +.Nm wcstof , +.Nm wcstod , +.Nm wcstold +.Nd "convert string to float, double or long double" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft float +.Fn wcstof "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" +.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" +.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 +functios. +Refer to +.Xr strtod 3 +for details. +.Sh SEE ALSO +.Xr strtod 3 , +.Xr wcstol 3 , +.Sh STANDARDS +The +.Fn wcstof , +.Fn wcstod +and +.Fn wcstold +functions conform to +.St -isoC-99 . diff --git a/locale/FreeBSD/wcstod.c b/locale/FreeBSD/wcstod.c new file mode 100644 index 0000000..656e5e5 --- /dev/null +++ b/locale/FreeBSD/wcstod.c @@ -0,0 +1,107 @@ +/*- + * 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.2 2003/02/22 00:06:05 tjr Exp $"); + +#include +#include +#include + +/* + * 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(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + static const mbstate_t initial; + mbstate_t state; + double val; + char *buf, *end, *p; + const wchar_t *wcp; + size_t clen, len; + + while (iswspace(*nptr)) + nptr++; + + /* + * 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. + */ + state = initial; + wcp = nptr; + if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = malloc(len + 1)) == NULL) + return (0.0); + state = initial; + wcsrtombs(buf, &wcp, len + 1, &state); + + /* Let strtod() do most of the work for us. */ + val = strtod(buf, &end); + + /* + * 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) { +#if 1 /* Fast, assume 1:1 WC:MBS mapping. */ + *endptr = (wchar_t *)nptr + (end - buf); + (void)clen; + (void)p; +#else /* Slow, conservative approach. */ + state = initial; + *endptr = (wchar_t *)nptr; + p = buf; + while (p < end && + (clen = mbrlen(p, end - p, &state)) > 0) { + p += clen; + (*endptr)++; + } +#endif + } + + free(buf); + + return (val); +} diff --git a/locale/FreeBSD/wcstof.c b/locale/FreeBSD/wcstof.c new file mode 100644 index 0000000..19836cb --- /dev/null +++ b/locale/FreeBSD/wcstof.c @@ -0,0 +1,84 @@ +/*- + * 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.1 2003/03/13 06:29:53 tjr Exp $"); + +#include +#include +#include + +/* + * See wcstod() for comments as to the logic used. + */ +float +wcstof(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + static const mbstate_t initial; + mbstate_t state; + float val; + char *buf, *end, *p; + const wchar_t *wcp; + size_t clen, len; + + while (iswspace(*nptr)) + nptr++; + + state = initial; + wcp = nptr; + if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = malloc(len + 1)) == NULL) + return (0.0); + state = initial; + wcsrtombs(buf, &wcp, len + 1, &state); + + val = strtof(buf, &end); + + if (endptr != NULL) { +#if 1 /* Fast, assume 1:1 WC:MBS mapping. */ + *endptr = (wchar_t *)nptr + (end - buf); + (void)clen; + (void)p; +#else /* Slow, conservative approach. */ + state = initial; + *endptr = (wchar_t *)nptr; + p = buf; + while (p < end && + (clen = mbrlen(p, end - p, &state)) > 0) { + p += clen; + (*endptr)++; + } +#endif + } + + free(buf); + + return (val); +} diff --git a/locale/FreeBSD/wcstoimax.c b/locale/FreeBSD/wcstoimax.c new file mode 100644 index 0000000..09e7817 --- /dev/null +++ b/locale/FreeBSD/wcstoimax.c @@ -0,0 +1,128 @@ +/*- + * 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 +#include +#include +#include +#include + +/* + * Convert a wide character string to an intmax_t integer. + */ +intmax_t +wcstoimax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + const wchar_t *s; + uintmax_t acc; + wchar_t c; + uintmax_t cutoff; + int neg, any, cutlim; + + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + 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(c)) + c = digittoint(c); + 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); +} diff --git a/locale/FreeBSD/wcstol.3 b/locale/FreeBSD/wcstol.3 new file mode 100644 index 0000000..306f223 --- /dev/null +++ b/locale/FreeBSD/wcstol.3 @@ -0,0 +1,94 @@ +.\" 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 wcstol , wcstoul , +.Nm wcstoll , wcstoull , +.Nm wcstoimax , wcstoumax +.Nd "convert a wide character string value to a" +.Vt long , +.Vt "unsigned long" , +.Vt "long long" , +.Vt "unsigned long long" , +.Vt intmax_t +or +.Vt uintmax_t +integer +.Sh LIBRARY +.Lb libc +.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" +.Ft "long long" +.Fn wcstoll "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Ft "unsigned long long" +.Fn wcstoull "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.In inttypes.h +.Ft intmax_t +.Fn wcstoimax "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Ft uintmax_t +.Fn wcstoumax "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.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. +.Sh SEE ALSO +.Xr strtol 3 , +.Xr strtoul 3 +.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/FreeBSD/wcstol.c b/locale/FreeBSD/wcstol.c new file mode 100644 index 0000000..ae51c2e --- /dev/null +++ b/locale/FreeBSD/wcstol.c @@ -0,0 +1,121 @@ +/*- + * 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 +#include +#include +#include +#include + +/* + * Convert a string to a long integer. + */ +long +wcstol(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + const wchar_t *s; + unsigned long acc; + wchar_t c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + 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(c)) + c = digittoint(c); + 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); +} diff --git a/locale/FreeBSD/wcstold.c b/locale/FreeBSD/wcstold.c new file mode 100644 index 0000000..b468f9a --- /dev/null +++ b/locale/FreeBSD/wcstold.c @@ -0,0 +1,84 @@ +/*- + * 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.1 2003/03/13 06:29:53 tjr Exp $"); + +#include +#include +#include + +/* + * See wcstod() for comments as to the logic used. + */ +long double +wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + static const mbstate_t initial; + mbstate_t state; + long double val; + char *buf, *end, *p; + const wchar_t *wcp; + size_t clen, len; + + while (iswspace(*nptr)) + nptr++; + + state = initial; + wcp = nptr; + if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = malloc(len + 1)) == NULL) + return (0.0); + state = initial; + wcsrtombs(buf, &wcp, len + 1, &state); + + val = strtold(buf, &end); + + if (endptr != NULL) { +#if 1 /* Fast, assume 1:1 WC:MBS mapping. */ + *endptr = (wchar_t *)nptr + (end - buf); + (void)clen; + (void)p; +#else /* Slow, conservative approach. */ + state = initial; + *endptr = (wchar_t *)nptr; + p = buf; + while (p < end && + (clen = mbrlen(p, end - p, &state)) > 0) { + p += clen; + (*endptr)++; + } +#endif + } + + free(buf); + + return (val); +} diff --git a/locale/FreeBSD/wcstoll.c b/locale/FreeBSD/wcstoll.c new file mode 100644 index 0000000..a48056c --- /dev/null +++ b/locale/FreeBSD/wcstoll.c @@ -0,0 +1,127 @@ +/*- + * 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 +#include +#include +#include +#include + +/* + * Convert a wide character string to a long long integer. + */ +long long +wcstoll(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + const wchar_t *s; + unsigned long long acc; + wchar_t c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * See strtoll for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + 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(c)) + c = digittoint(c); + 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); +} diff --git a/locale/FreeBSD/wcstombs.c b/locale/FreeBSD/wcstombs.c new file mode 100644 index 0000000..d0e49cb --- /dev/null +++ b/locale/FreeBSD/wcstombs.c @@ -0,0 +1,91 @@ +/*- + * 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/wcstombs.c,v 1.5 2002/10/27 10:41:21 tjr Exp $"); + +#include +#include +#include +#include +#include + +size_t +wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) +{ + char buf[MB_LEN_MAX]; + char *e; + int cnt, nb; + + if (pwcs == NULL || n > INT_MAX) { + errno = EINVAL; + return (-1); + } + + cnt = 0; + + if (s == NULL) { + /* Convert and count only, do not store. */ + while (*pwcs != L'\0') { + if (sputrune(*pwcs++, buf, MB_LEN_MAX, &e) == 0) { + errno = EILSEQ; + return (-1); + } + cnt += e - buf; + } + return (cnt); + } + + /* Convert, store and count characters. */ + nb = n; + while (nb > 0) { + if (*pwcs == L'\0') { + *s = '\0'; + break; + } + if (sputrune(*pwcs++, s, nb, &e) == 0) { + errno = EILSEQ; + return (-1); + } + if (e == NULL) /* too long */ + return (cnt); + cnt += e - s; + nb -= e - s; + s = e; + } + + return (cnt); +} diff --git a/locale/FreeBSD/wcstoul.c b/locale/FreeBSD/wcstoul.c new file mode 100644 index 0000000..f3b8b49 --- /dev/null +++ b/locale/FreeBSD/wcstoul.c @@ -0,0 +1,119 @@ +/* + * 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 +#include +#include +#include +#include + +/* + * Convert a wide character string to an unsigned long integer. + */ +unsigned long +wcstoul(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + const wchar_t *s; + unsigned long acc; + wchar_t c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + 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(c)) + c = digittoint(c); + 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); +} diff --git a/locale/ansi.c b/locale/FreeBSD/wcstoull.c similarity index 52% rename from locale/ansi.c rename to locale/FreeBSD/wcstoull.c index c0871fe..fd9558b 100644 --- a/locale/ansi.c +++ b/locale/FreeBSD/wcstoull.c @@ -1,10 +1,7 @@ /*- - * Copyright (c) 1993 + * Copyright (c) 1992, 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: @@ -34,118 +31,96 @@ * SUCH DAMAGE. */ +#include +#if 0 #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ansi.c 8.1 (Berkeley) 6/27/93"; +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 +#include #include -#include -#include - -int -mblen(s, n) - const char *s; - size_t n; -{ - char const *e; - - if (s == 0 || *s == 0) - return (0); /* No support for state dependent encodings. */ - - if (sgetrune(s, n, &e) == _INVALID_RUNE) - return (s - e); - return (e - s); -} - -int -mbtowc(pwc, s, n) - wchar_t *pwc; - const char *s; - size_t n; -{ - char const *e; - rune_t r; - - if (s == 0 || *s == 0) - return (0); /* No support for state dependent encodings. */ - - if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) - return (s - e); - if (pwc) - *pwc = r; - return (e - s); -} +#include +#include +#include -int -wctomb(s, wchar) - char *s; - wchar_t wchar; +/* + * Convert a wide character string to an unsigned long long integer. + */ +unsigned long long +wcstoull(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) { - char *e; - - if (s == 0) - return (0); /* No support for state dependent encodings. */ - - if (wchar == 0) { - *s = 0; - return (1); + const wchar_t *s; + unsigned long long acc; + wchar_t c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * See strtoull for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; } - - sputrune(wchar, s, MB_CUR_MAX, &e); - return (e ? e - s : -1); -} - -size_t -mbstowcs(pwcs, s, n) - wchar_t *pwcs; - const char *s; - size_t n; -{ - char const *e; - int cnt = 0; - - if (!pwcs || !s) - return (-1); - - while (n-- > 0) { - *pwcs = sgetrune(s, MB_LEN_MAX, &e); - if (*pwcs == _INVALID_RUNE) - return (-1); - if (*pwcs++ == 0) - break; - s = e; - ++cnt; + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; } - return (cnt); -} - -size_t -wcstombs(s, pwcs, n) - char *s; - const wchar_t *pwcs; - size_t n; -{ - char *e; - int cnt, nb; - - if (!pwcs || !s || n > INT_MAX) - return (-1); - - nb = n; - cnt = 0; - while (nb > 0) { - if (*pwcs == 0) { - *s = 0; + 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(c)) + c = digittoint(c); + 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 (!sputrune(*pwcs++, s, nb, &e)) - return (-1); /* encoding error */ - if (!e) /* too long */ - return (cnt); - cnt += e - s; - nb -= e - s; - s = e; } - return (cnt); + 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); } diff --git a/locale/FreeBSD/wcstoumax.c b/locale/FreeBSD/wcstoumax.c new file mode 100644 index 0000000..01e25d5 --- /dev/null +++ b/locale/FreeBSD/wcstoumax.c @@ -0,0 +1,126 @@ +/*- + * 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 +#include +#include +#include +#include + +/* + * Convert a wide character string to a uintmax_t integer. + */ +uintmax_t +wcstoumax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + const wchar_t *s; + uintmax_t acc; + wchar_t c; + uintmax_t cutoff; + int neg, any, cutlim; + + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + 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(c)) + c = digittoint(c); + 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); +} diff --git a/locale/FreeBSD/wctob.c b/locale/FreeBSD/wctob.c new file mode 100644 index 0000000..290f327 --- /dev/null +++ b/locale/FreeBSD/wctob.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/locale/wctob.c,v 1.1 2002/08/03 13:49:55 tjr Exp $"); + +#include +#include + +int +wctob(wint_t c) +{ + char cc; + + if (c == WEOF || sputrune(c, &cc, 1, NULL) != 1) + return (EOF); + return ((unsigned char)cc); +} diff --git a/locale/FreeBSD/wctomb.c b/locale/FreeBSD/wctomb.c new file mode 100644 index 0000000..8c441f1 --- /dev/null +++ b/locale/FreeBSD/wctomb.c @@ -0,0 +1,66 @@ +/*- + * 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/wctomb.c,v 1.3 2002/10/27 10:41:21 tjr Exp $"); + +#include +#include +#include +#include +#include + +int +wctomb(char *s, wchar_t wchar) +{ + char *e; + + if (s == NULL) + /* No support for state dependent encodings. */ + return (0); + + if (wchar == L'\0') { + *s = '\0'; + return (1); + } + + sputrune(wchar, s, MB_CUR_MAX, &e); + if (e == NULL) { + errno = EILSEQ; + return (-1); + } + return (e - s); +} diff --git a/locale/FreeBSD/wctrans.3 b/locale/FreeBSD/wctrans.3 new file mode 100644 index 0000000..0f2bc65 --- /dev/null +++ b/locale/FreeBSD/wctrans.3 @@ -0,0 +1,122 @@ +.\" 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 , wctrans +.Nd "wide character mapping functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fn towctrans "wint_t wc" "wctrans_t desc" +.Ft wctrans_t +.Fn wctrans "const char *charclass" +.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 . +.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 +.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/FreeBSD/wctrans.c b/locale/FreeBSD/wctrans.c new file mode 100644 index 0000000..d056bfa --- /dev/null +++ b/locale/FreeBSD/wctrans.c @@ -0,0 +1,84 @@ +/*- + * 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.2 2002/11/09 05:19:08 tjr Exp $"); + +#include +#include +#include +#include + +enum { + _WCT_ERROR = 0, + _WCT_TOLOWER = 1, + _WCT_TOUPPER = 2 +}; + +/* + * TODO: Supply a macro version of this. + */ +wint_t +towctrans(wint_t wc, wctrans_t desc) +{ + + switch (desc) { + case _WCT_TOLOWER: + wc = towlower(wc); + break; + case _WCT_TOUPPER: + wc = towupper(wc); + break; + case _WCT_ERROR: + default: + errno = EINVAL; + break; + } + + return (wc); +} + +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); +} diff --git a/locale/FreeBSD/wctype.3 b/locale/FreeBSD/wctype.3 new file mode 100644 index 0000000..b24edcb --- /dev/null +++ b/locale/FreeBSD/wctype.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/wctype.3,v 1.4 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd October 3, 2002 +.Dt WCTYPE 3 +.Os +.Sh NAME +.Nm iswctype , wctype +.Nd "wide character class functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft int +.Fn iswctype "wint_t wc" "wctype_t charclass" +.Ft wctype_t +.Fn wctype "const char *property" +.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 phonogram" ".Li print" ".Li special" +.It Li "alnum cntrl ideogram print special" +.It Li "alpha digit lower punct upper" +.It Li "blank graph phonogram space xdigit" +.El +.Pp +The +.Fn iswctype +function checks whether the wide character +.Fa wc +is in the character class +.Fa charclass . +.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 +.Sh STANDARDS +The +.Fn iswctype +and +.Fn wctype +functions conform to +.St -p1003.1-2001 . +The +.Dq Li ideogram , +.Dq Li phonogram +and +.Dq Li special +character classes are extensions. +.Sh HISTORY +The +.Fn iswctype +and +.Fn wctype +functions first appeared in +.Fx 5.0 . diff --git a/locale/FreeBSD/wctype.c b/locale/FreeBSD/wctype.c new file mode 100644 index 0000000..c28015e --- /dev/null +++ b/locale/FreeBSD/wctype.c @@ -0,0 +1,73 @@ +/*- + * 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.2 2002/08/04 12:43:53 tjr Exp $"); + +#include +#include +#include + +#undef iswctype +int +iswctype(wint_t wc, wctype_t charclass) +{ + + return (__istype(wc, charclass)); +} + +wctype_t +wctype(const char *property) +{ + 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 */ + { NULL, 0UL }, /* Default */ + }; + int i; + + i = 0; + while (props[i].name != NULL && strcmp(props[i].name, property) != 0) + i++; + + return (props[i].mask); +} diff --git a/locale/FreeBSD/wcwidth.3 b/locale/FreeBSD/wcwidth.3 new file mode 100644 index 0000000..ed28bf5 --- /dev/null +++ b/locale/FreeBSD/wcwidth.3 @@ -0,0 +1,86 @@ +.\" 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.3 2002/11/29 17:35:09 ru Exp $ +.\" +.Dd October 3, 2002 +.Dt WCWIDTH 3 +.Os +.Sh NAME +.Nm wcwidth +.Nd "number of column positions of a wide-character code" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fn wcwidth "wchar_t wc" +.Sh DESCRIPTION +The +.Fn wcwidth +function determines the number of column positions required to +display the wide character +.Fa wc . +.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) { + if ((w = wcwidth(ch)) > 0) + column += w; + if (column >= 20) { + putwchar(L'\en'); + column = 0; + } + putwchar(ch); + if (ch == L'\en') + column = 0; +} +.Ed +.Sh SEE ALSO +.Xr iswprint 3 , +.Xr wcswidth 3 +.Sh STANDARDS +The +.Fn wcwidth +function conforms to +.St -p1003.1-2001 . diff --git a/locale/FreeBSD/wcwidth.c b/locale/FreeBSD/wcwidth.c new file mode 100644 index 0000000..79f59dd --- /dev/null +++ b/locale/FreeBSD/wcwidth.c @@ -0,0 +1,65 @@ +/* + * 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/wcwidth.c,v 1.5 2002/08/19 20:32:27 ache Exp $"); + +#include +#include + +#define _CTYPE_SWM 0xe0000000L /* Mask to get screen width data */ +#define _CTYPE_SWS 30 /* Bits to shift to get width */ + +int +wcwidth(wchar_t wc) +{ + int width; + + if (wc == L'\0') + return (0); + + width = __maskrune(wc, _CTYPE_SWM); + + /* 0 is autowidth (default) */ + return (width ? (int)((unsigned)width >> _CTYPE_SWS) + : (iswprint(wc) ? 1 : -1)); +} + diff --git a/locale/Makefile.inc b/locale/Makefile.inc index f5c3b13..6be6677 100644 --- a/locale/Makefile.inc +++ b/locale/Makefile.inc @@ -1,21 +1,58 @@ # from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 -# $FreeBSD: src/lib/libc/locale/Makefile.inc,v 1.20 2001/05/03 15:12:52 phantom Exp $ +# $FreeBSD: src/lib/libc/locale/Makefile.inc,v 1.43 2003/03/13 06:29:53 tjr Exp $ # locale sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/locale ${.CURDIR}/locale -SRCS+= ansi.c big5.c collate.c collcmp.c euc.c frune.c isctype.c \ - lconv.c localeconv.c mbrune.c mskanji.c nomacros.c none.c rune.c \ +.include "Makefile.fbsd_begin" +FBSDSRCS= big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c frune.c \ + isctype.c iswctype.c \ + ldpart.c lmessages.c lmonetary.c lnumeric.c localeconv.c mblen.c \ + mbrlen.c \ + mbrtowc.c mbrune.c mbsinit.c mbsrtowcs.c mbtowc.c mbstowcs.c \ + mskanji.c nl_langinfo.c nomacros.c none.c rune.c \ runetype.c setinvalidrune.c setlocale.c setrunelocale.c table.c \ - tolower.c toupper.c utf2.c + tolower.c toupper.c utf2.c utf8.c wcrtomb.c wcsrtombs.c wcsftime.c \ + wcstof.c wcstod.c \ + wcstoimax.c wcstol.c wcstold.c wcstoll.c \ + wcstombs.c \ + wcstoul.c wcstoull.c wcstoumax.c wctob.c wctomb.c wctrans.c wctype.c \ + wcwidth.c +FBSDORIGHDRS= collate.h ldpart.h lmessages.h lmonetary.h lnumeric.h setlocale.h +.include "Makefile.fbsd_end" + +# Begin hack for 3333969 + +CFLAGS += -D__APPLE_PR_3333969_HACK__ + +SRCS += lconv.c + +# End hack for 3333969 .if ${LIB} == "c" -MAN3+= ctype.3 isalnum.3 isalpha.3 isascii.3 isblank.3 iscntrl.3 \ - isdigit.3 isgraph.3 islower.3 isprint.3 ispunct.3 isspace.3 \ - isupper.3 isxdigit.3 mbrune.3 multibyte.3 nl_langinfo.3 rune.3 \ - setlocale.3 toascii.3 tolower.3 toupper.3 -MAN4+= euc.4 utf2.4 +.include "Makefile.fbsd_begin" +FBSDMAN3= btowc.3 ctype.3 digittoint.3 isalnum.3 isalpha.3 isascii.3 isblank.3 \ + iscntrl.3 isdigit.3 isgraph.3 islower.3 isprint.3 ispunct.3 isspace.3 \ + isupper.3 iswalnum.3 isxdigit.3 mbrlen.3 mbrtowc.3 mbrune.3 mbsinit.3 \ + mbsrtowcs.3 multibyte.3 nl_langinfo.3 rune.3 setlocale.3 toascii.3 \ + tolower.3 toupper.3 towlower.3 towupper.3 wcsftime.3 wcrtomb.3 \ + wcsrtombs.3 wcstod.3 wcstol.3 wctrans.3 wctype.3 wcwidth.3 +FBSDMAN4= euc.4 utf2.4 +FBSDMAN5= utf8.5 +.include "Makefile.fbsd_end" +MLINKS+=btowc.3 wctob.3 +MLINKS+=ctype.3 isideogram.3 ctype.3 isphonogram.3 ctype.3 isspecial.3 \ + ctype.3 isrune.3 +MLINKS+=isdigit.3 isnumber.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 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+=isxdigit.3 ishexnumber.3 MLINKS+=mbrune.3 mbmb.3 mbrune.3 mbrrune.3 MLINKS+=multibyte.3 mblen.3 multibyte.3 mbstowcs.3 multibyte.3 mbtowc.3 \ multibyte.3 wcstombs.3 multibyte.3 wctomb.3 @@ -23,4 +60,9 @@ 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+=setlocale.3 localeconv.3 +MLINKS+=wcstod.3 wcstof.3 wcstod.3 wcstold.3 +MLINKS+=wcstol.3 wcstoul.3 wcstol.3 wcstoll.3 wcstol.3 wcstoull.3 \ + wcstol.3 wcstoimax.3 wcstol.3 wcstoumax.3 +MLINKS+=wctrans.3 towctrans.3 +MLINKS+=wctype.3 iswctype.3 .endif diff --git a/locale/collate.c b/locale/collate.c deleted file mode 100644 index 5ef2ebb..0000000 --- a/locale/collate.c +++ /dev/null @@ -1,212 +0,0 @@ -/*- - * 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.c,v 1.21.2.1 2001/03/05 10:10:22 obrien Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "collate.h" -#include "setlocale.h" - -int __collate_load_error = 1; -int __collate_substitute_nontrivial; -char __collate_version[STR_LEN]; -u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; -struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; -struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; - -#define FREAD(a, b, c, d) \ - do { \ - if (fread(a, b, c, d) != c) { \ - fclose(d); \ - return -1; \ - } \ - } while(0) - -void __collate_err(int ex, const char *f) ; - -int -__collate_load_tables(encoding) - char *encoding; -{ - char buf[PATH_MAX]; - FILE *fp; - int i, save_load_error; - - save_load_error = __collate_load_error; - __collate_load_error = 1; - if (!encoding) { - __collate_load_error = save_load_error; - return -1; - } - if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) - return 0; - if (!_PathLocale) { - __collate_load_error = save_load_error; - return -1; - } - /* 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) { - __collate_load_error = save_load_error; - return -1; - } - FREAD(__collate_version, sizeof(__collate_version), 1, fp); - if (strcmp(__collate_version, COLLATE_VERSION) != 0) { - fclose(fp); - return -1; - } - FREAD(__collate_substitute_table, sizeof(__collate_substitute_table), - 1, fp); - FREAD(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, - fp); - FREAD(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, - fp); - fclose(fp); - __collate_load_error = 0; - - __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; - } - } - - return 0; -} - -u_char * -__collate_substitute(s) - const u_char *s; -{ - int dest_len, len, nlen; - int delta = strlen(s); - u_char *dest_str = NULL; - - if(s == NULL || *s == '\0') - return __collate_strdup(""); - delta += delta / 8; - dest_str = malloc(dest_len = delta); - if(dest_str == NULL) - __collate_err(EX_OSERR, __FUNCTION__); - len = 0; - while(*s) { - nlen = len + strlen(__collate_substitute_table[*s]); - if (dest_len <= nlen) { - dest_str = reallocf(dest_str, dest_len = nlen + delta); - if(dest_str == NULL) - __collate_err(EX_OSERR, __FUNCTION__); - } - strcpy(dest_str + len, __collate_substitute_table[*s++]); - len = nlen; - } - return dest_str; -} - -void -__collate_lookup(t, len, prim, sec) - const u_char *t; - int *len, *prim, *sec; -{ - struct __collate_st_chain_pri *p2; - - *len = 1; - *prim = *sec = 0; - for(p2 = __collate_chain_pri_table; p2->str[0]; p2++) { - if(strncmp(t, p2->str, strlen(p2->str)) == 0) { - *len = strlen(p2->str); - *prim = p2->prim; - *sec = p2->sec; - return; - } - } - *prim = __collate_char_pri_table[*t].prim; - *sec = __collate_char_pri_table[*t].sec; -} - -u_char * -__collate_strdup(s) - u_char *s; -{ - u_char *t = strdup(s); - - if (t == NULL) - __collate_err(EX_OSERR, __FUNCTION__); - return t; -} - -void -__collate_err(int ex, const char *f) -{ - char **__progname = _NSGetProgname(); - const char *s; - int serrno = errno; - - s = *__progname; - 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); -} - -#ifdef COLLATE_DEBUG -void -__collate_print_tables() -{ - int i; - struct __collate_st_chain_pri *p2; - - 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]; p2++) - printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); - printf("Char priority table:\n"); - 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); -} -#endif diff --git a/locale/lconv.c b/locale/lconv.c index f1212b0..f8b429d 100644 --- a/locale/lconv.c +++ b/locale/lconv.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -31,6 +55,13 @@ * SUCH DAMAGE. */ +#ifdef __APPLE_PR_3333969_HACK__ +/* + * 3333969: SPSS links directly to __lconv, which is gone in Panther. + * So we resurrect the __lconv symbol, which points to data that never + * changes (as it never did in Jaguar). This should be removed for Merlot. + */ + #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)lconv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ @@ -68,3 +99,5 @@ static struct lconv C_lconv = { * Current locale conversion. */ struct lconv *__lconv = &C_lconv; + +#endif // __APPLE_PR_3333969_HACK__ diff --git a/mach/Makefile.inc b/mach/Makefile.inc index 10bda18..353fc65 100644 --- a/mach/Makefile.inc +++ b/mach/Makefile.inc @@ -8,6 +8,11 @@ .include "${.CURDIR}/${MACHINE_ARCH}/mach/Makefile.inc" .endif +MD_MIGDEFS += task.defs \ + thread_act.defs + +MD_MIGHDRS += ${MD_MIGDEFS:.defs=.h} + MIGDEFS += \ clock.defs \ clock_priv.defs \ @@ -19,19 +24,16 @@ MIGDEFS += \ mach_host.defs \ processor.defs \ processor_set.defs \ - task.defs \ - thread_act.defs \ vm_map.defs -#MIGHDRS = ${MIGDEFS:S/.defs$/.h/:S/^/${.CURDIR}\/mach\//} -MIGHDRS = ${MIGDEFS:S/.defs$/.h/} +MIGHDRS = ${MIGDEFS:.defs=.h} MIGHDRS += clock_reply.h MACH_INSTHDRS += ${MIGHDRS} # These files are generated from the .defs files -MIGSRCS = ${MIGDEFS:S/.defs$/User.c/} +MIGSRCS = ${MIGDEFS:.defs=User.c} ${MD_MIGDEFS:.defs=User.c} -SRCS+= ${MIGDEFS:S/.defs$/User.defs/} \ +SRCS += ${MIGSRCS} \ bootstrap_ports.c \ clock_sleep.c \ error_codes.c \ @@ -59,45 +61,6 @@ SRCS+= ${MIGDEFS:S/.defs$/User.defs/} \ semaphore.c \ slot_name.c -CLEANFILES += ${MIGHDRS} ${MIGHDRS:S/.h$/User.c/} \ - ${MIGHDRS:S/.h/Server.c/} exc.h excUser.c excServer.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 - -${MIGDEFS:S/.defs$/User.So/}: - mig -user ${.TARGET:S/.So$/.c/} \ - -server ${.TARGET:S/User.So$/Server.c/} \ - -header ${.TARGET:S/User.So$/.h/} \ - ${.CURDIR}/mach/${.TARGET:S/User.So$/.defs/} - ${CC} ${CFLAGS} -Os -c ${.TARGET:S/.So$/.c/}\ - -o ${.TARGET} -${MIGDEFS:S/.defs$/User.do/}: - mig -user ${.TARGET:S/.do$/.c/} \ - -server ${.TARGET:S/User.do$/Server.c/} \ - -header ${.TARGET:S/User.do$/.h/} \ - ${.CURDIR}/mach/${.TARGET:S/User.do$/.defs/} - ${CC} -g -DDEBUG ${CFLAGS} -c ${.TARGET:S/.do$/.c/}\ - -o ${.TARGET} -${MIGDEFS:S/.defs$/User.po/}: - mig -user ${.TARGET:S/.po$/.c/} \ - -server ${.TARGET:S/User.po$/Server.c/} \ - -header ${.TARGET:S/User.po$/.h/} \ - ${.CURDIR}/mach/${.TARGET:S/User.po$/.defs/} - ${CC} -pg -DPROFILE ${CFLAGS} -c ${.TARGET:S/.po$/.c/}\ - -o ${.TARGET} -${MIGDEFS:S/.defs$/User.o/}: - mig -user ${.TARGET:S/.o$/.c/} \ - -server ${.TARGET:S/User.o$/Server.c/} \ - -header ${.TARGET:S/User.o$/.h/} \ - ${.CURDIR}/mach/${.TARGET:S/User.o$/.defs/} - ${CC} -static ${CFLAGS} -c ${.TARGET:S/.o$/.c/}\ - -o ${.TARGET} - -excServer.c: ${.CURDIR}/mach/exc.defs - mig -user excUser.c -server excServer.c -header exc.h \ - ${.CURDIR}/mach/exc.defs -excUser.c: ${.CURDIR}/mach/exc.defs - mig -user excUser.c -server excServer.c -header exc.h \ - ${.CURDIR}/mach/exc.defs -notifyUser.c: ${.CURDIR}/mach/notify.defs - mig -user notifyUser.c -server notifyServer.c -header notify.h \ - ${.CURDIR}/mach/notify.defs diff --git a/mach/clock.defs b/mach/clock.defs index 1695171..4b78f55 100644 --- a/mach/clock.defs +++ b/mach/clock.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index d419faf..ddf17f1 100644 --- a/mach/clock_priv.defs +++ b/mach/clock_priv.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/error_codes.c b/mach/error_codes.c index 184969d..55856ee 100644 --- a/mach/error_codes.c +++ b/mach/error_codes.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ diff --git a/mach/errorlib.h b/mach/errorlib.h index df06289..9f06fcf 100644 --- a/mach/errorlib.h +++ b/mach/errorlib.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ diff --git a/mach/exc_catcher.c b/mach/exc_catcher.c index 0b5bf51..f5ccbc4 100644 --- a/mach/exc_catcher.c +++ b/mach/exc_catcher.c @@ -33,6 +33,7 @@ #include #include #include +#include __private_extern__ kern_return_t internal_catch_exception_raise ( mach_port_t exception_port, diff --git a/mach/exc_catcher_state.c b/mach/exc_catcher_state.c index 372f0f3..f58c914 100644 --- a/mach/exc_catcher_state.c +++ b/mach/exc_catcher_state.c @@ -33,6 +33,7 @@ #include #include #include +#include __private_extern__ kern_return_t internal_catch_exception_raise_state ( mach_port_t exception_port, diff --git a/mach/exc_catcher_state_identity.c b/mach/exc_catcher_state_identity.c index b60108a..dc12b56 100644 --- a/mach/exc_catcher_state_identity.c +++ b/mach/exc_catcher_state_identity.c @@ -33,6 +33,7 @@ #include #include #include +#include __private_extern__ kern_return_t internal_catch_exception_raise_state_identity ( mach_port_t exception_port, diff --git a/mach/externs.h b/mach/externs.h index 515646f..a5482a9 100644 --- a/mach/externs.h +++ b/mach/externs.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ diff --git a/mach/fprintf_stderr.c b/mach/fprintf_stderr.c index a2f70f7..322a6be 100644 --- a/mach/fprintf_stderr.c +++ b/mach/fprintf_stderr.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ * diff --git a/mach/headers/Makefile.inc b/mach/headers/Makefile.inc index a01b9f7..f747c3d 100644 --- a/mach/headers/Makefile.inc +++ b/mach/headers/Makefile.inc @@ -4,5 +4,7 @@ MACH_INSTHDRS += mach.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 index aa270da..d959f36 100644 --- a/mach/headers/errorlib.h +++ b/mach/headers/errorlib.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ @@ -65,6 +89,10 @@ struct error_system { 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 index 924fee0..be81873 100644 --- a/mach/headers/mach.h +++ b/mach/headers/mach.h @@ -71,6 +71,9 @@ #include #include +#include + +__BEGIN_DECLS /* * Standard prototypes */ @@ -126,4 +129,6 @@ 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 index 6323a12..f101289 100644 --- a/mach/headers/mach_error.h +++ b/mach/headers/mach_error.h @@ -61,6 +61,9 @@ #include +#include + +__BEGIN_DECLS char *mach_error_string( /* * Returns a string appropriate to the error argument given @@ -82,5 +85,6 @@ char *mach_error_type( */ mach_error_t error_value ); +__END_DECLS #endif /* _MACH_ERROR_ */ diff --git a/mach/headers/mach_init.h b/mach/headers/mach_init.h index 0161ff5..5f5d5ca 100644 --- a/mach/headers/mach_init.h +++ b/mach/headers/mach_init.h @@ -58,6 +58,9 @@ #include #include +#include + +__BEGIN_DECLS /* * Kernel-related ports; how a task/thread controls itself */ @@ -110,6 +113,6 @@ extern vm_size_t vm_page_size; */ 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 index 6373e90..7a9f49e 100644 --- a/mach/headers/mach_interface.h +++ b/mach/headers/mach_interface.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 diff --git a/mach/headers/port_obj.h b/mach/headers/port_obj.h index 796972c..4c60f6f 100644 --- a/mach/headers/port_obj.h +++ b/mach/headers/port_obj.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ @@ -18,9 +42,13 @@ struct port_obj_tentry { int pos_type; }; +#include + +__BEGIN_DECLS extern void port_obj_init(int); extern struct port_obj_tentry *port_obj_table; extern int port_obj_table_size; +__END_DECLS #ifndef PORT_OBJ_ASSERT diff --git a/i386/sys/shm_unlink.s b/mach/headers/task.h similarity index 82% rename from i386/sys/shm_unlink.s rename to mach/headers/task.h index 352e95e..d5bdab0 100644 --- a/i386/sys/shm_unlink.s +++ b/mach/headers/task.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,10 +22,10 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#include "SYS.h" - -UNIX_SYSCALL(shm_unlink, 3) - ret +#if defined(__i386__) +#include +#elif defined(__ppc__) +#include +#else +#error unknown architecture +#endif diff --git a/mach/headers/thread_act.h b/mach/headers/thread_act.h new file mode 100644 index 0000000..ae22d7e --- /dev/null +++ b/mach/headers/thread_act.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 +#elif defined(__ppc__) +#include +#else +#error unknown architecture +#endif diff --git a/mach/host_priv.defs b/mach/host_priv.defs index 060900d..bfe8aae 100644 --- a/mach/host_priv.defs +++ b/mach/host_priv.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 96999e5..39cc92a 100644 --- a/mach/host_security.defs +++ b/mach/host_security.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index c7e9270..96e102e 100644 --- a/mach/ledger.defs +++ b/mach/ledger.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index c62bb42..ed8a276 100644 --- a/mach/lock_set.defs +++ b/mach/lock_set.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index b1997c8..3d67b85 100644 --- a/mach/mach_error.c +++ b/mach/mach_error.c @@ -62,6 +62,8 @@ #include #include "errorlib.h" +int fprintf_stderr(const char *format, ...); + void mach_error( str, err ) char *str; diff --git a/mach/mach_error_string.c b/mach/mach_error_string.c index 5934f1c..a3dd3f5 100644 --- a/mach/mach_error_string.c +++ b/mach/mach_error_string.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ diff --git a/mach/mach_init.c b/mach/mach_init.c index 585657f..bcf94b3 100644 --- a/mach/mach_init.c +++ b/mach/mach_init.c @@ -103,7 +103,6 @@ mach_host_self() int mach_init_doit(int forkchild) { - mach_msg_type_number_t host_info_size; host_t host; /* @@ -140,14 +139,6 @@ int mach_init_doit(int forkchild) * Cache some other valuable system constants */ -#ifdef HOST_MACH_MSG_TRAP - host_info_size = 0; - _host_mach_msg_trap_return_ = host_info(host, - HOST_MACH_MSG_TRAP, - 0, - &host_info_size); -#endif - (void)host_page_size(host, &vm_page_size); mach_port_deallocate(mach_task_self_, host); diff --git a/mach/mach_init_ports.c b/mach/mach_init_ports.c index b178e57..37c442f 100644 --- a/mach/mach_init_ports.c +++ b/mach/mach_init_ports.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ @@ -29,6 +53,7 @@ */ #include +#include #include "externs.h" mach_port_t bootstrap_port = MACH_PORT_NULL; diff --git a/mach/mach_msg.c b/mach/mach_msg.c index 3771c26..9af534c 100644 --- a/mach/mach_msg.c +++ b/mach/mach_msg.c @@ -56,21 +56,8 @@ #include #include -#ifdef HOST_MACH_MSG_TRAP -__private_extern__ kern_return_t _host_mach_msg_trap_return_ = KERN_FAILURE; - -#define MACH_MSG_TRAP(msg, opt, ssize, rsize, rname, to, not) \ - ((_host_mach_msg_trap_return_ == KERN_SUCCESS) ? \ - mach_msg_trap((msg), (opt), (ssize), (rsize), (rname), (to), (not)) : \ - mach_msg_overwrite_trap((msg), (opt), (ssize), (rsize), (rname), \ - (to), (not), MACH_MSG_NULL, 0)) - -#else - -#define MACH_MSG_TRAP(msg, opt, ssize, rsize, rname, to, not) \ - mach_msg_overwrite_trap((msg), (opt), (ssize), (rsize), (rname), \ - (to), (not), MACH_MSG_NULL, 0)) -#endif +#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) @@ -499,7 +486,7 @@ mach_msg_server( kern_return_t kr; mach_port_t self = mach_task_self(); - options &= ~(MACH_SEND_MSG|MACH_RCV_MSG); + 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); @@ -589,7 +576,7 @@ mach_msg_server( 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, request_size); + &bufRequest->Head, 0); } if ((mr != MACH_SEND_INVALID_DEST) && diff --git a/mach/ms_thread_switch.c b/mach/ms_thread_switch.c index 2f6a6d6..72fc09e 100644 --- a/mach/ms_thread_switch.c +++ b/mach/ms_thread_switch.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ @@ -34,6 +58,8 @@ #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, diff --git a/mach/notify.defs b/mach/notify.defs index 2014be5..fc6581c 100644 --- a/mach/notify.defs +++ b/mach/notify.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 2411d52..dd6504d 100644 --- a/mach/panic.c +++ b/mach/panic.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ diff --git a/mach/port_obj.c b/mach/port_obj.c index 4d63221..5c313d2 100644 --- a/mach/port_obj.c +++ b/mach/port_obj.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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@ */ diff --git a/mach/processor.defs b/mach/processor.defs index bc58140..d740ea7 100644 --- a/mach/processor.defs +++ b/mach/processor.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 5504bc9..22b37a4 100644 --- a/mach/processor_set.defs +++ b/mach/processor_set.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 47ea27e..d03f1a6 100644 --- a/mach/sbrk.c +++ b/mach/sbrk.c @@ -46,10 +46,7 @@ static vm_address_t sbrk_curbrk; caddr_t sbrk(size) int size; { - vm_offset_t addr; kern_return_t ret; - caddr_t ocurbrk; - extern int end; if (sbrk_needs_init) { sbrk_needs_init = FALSE; @@ -64,10 +61,10 @@ caddr_t sbrk(size) if (size <= 0) return((caddr_t)sbrk_curbrk); + else if (size > sbrk_region_size) + return((caddr_t)-1); sbrk_curbrk += size; sbrk_region_size -= size; - if (sbrk_region_size < 0) - return((caddr_t)-1); return((caddr_t)(sbrk_curbrk - size)); } diff --git a/mach/servers/Makefile.inc b/mach/servers/Makefile.inc index d0ff159..a9ac676 100644 --- a/mach/servers/Makefile.inc +++ b/mach/servers/Makefile.inc @@ -14,32 +14,3 @@ SRCS+= ${SRVMIGDEFS:S/.defs$/User.defs/} CLEANFILES += ${SRVMIGHDRS} ${SRVMIGHDRS:S/.h$/User.c/} \ ${SRVMIGHDRS:S/.h$/Server.c/} - -${SRVMIGDEFS:S/.defs$/User.So/}: - mig -user ${.TARGET:S/.So$/.c/} \ - -server ${.TARGET:S/User.So$/Server.c/} \ - -header ${.TARGET:S/User.So$/.h/} \ - ${.CURDIR}/mach/servers/${.TARGET:S/User.So$/.defs/} - ${CC} ${CFLAGS} -Os -c ${.TARGET:S/.So$/.c/}\ - -o ${.TARGET} -${SRVMIGDEFS:S/.defs$/User.do/}: - mig -user ${.TARGET:S/.do$/.c/} \ - -server ${.TARGET:S/User.do$/Server.c/} \ - -header ${.TARGET:S/User.do$/.h/} \ - ${.CURDIR}/mach/servers/${.TARGET:S/User.do$/.defs/} - ${CC} -g -DDEBUG ${CFLAGS} -c ${.TARGET:S/.do$/.c/}\ - -o ${.TARGET} -${SRVMIGDEFS:S/.defs$/User.po/}: - mig -user ${.TARGET:S/.po$/.c/} \ - -server ${.TARGET:S/User.po$/Server.c/} \ - -header ${.TARGET:S/User.po$/.h/} \ - ${.CURDIR}/mach/servers/${.TARGET:S/User.po$/.defs/} - ${CC} -pg -DPROFILE ${CFLAGS} -c ${.TARGET:S/.po$/.c/}\ - -o ${.TARGET} -${SRVMIGDEFS:S/.defs$/User.o/}: - mig -user ${.TARGET:S/.o$/.c/} \ - -server ${.TARGET:S/User.o$/Server.c/} \ - -header ${.TARGET:S/User.o$/.h/} \ - ${.CURDIR}/mach/servers/${.TARGET:S/User.o$/.defs/} - ${CC} -static ${CFLAGS} -c ${.TARGET:S/.o$/.c/}\ - -o ${.TARGET} diff --git a/mach/servers/netname.defs b/mach/servers/netname.defs index 264495c..06363f9 100644 --- a/mach/servers/netname.defs +++ b/mach/servers/netname.defs @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 diff --git a/mach/slot_name.c b/mach/slot_name.c index 976db0f..af17981 100644 --- a/mach/slot_name.c +++ b/mach/slot_name.c @@ -56,8 +56,8 @@ void slot_name(cpu_type, cpu_subtype, cpu_name, cpu_subname) register char *subname = ""; const NXArchInfo *ai = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); if (ai != NULL) { - name = ai->name; - subname = ai->description; + name = (char *)ai->name; + subname = (char *)ai->description; } *cpu_name = name; *cpu_subname = subname; diff --git a/mach/task.defs b/mach/task.defs index af6399f..cf916bb 100644 --- a/mach/task.defs +++ b/mach/task.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 8c515f8..61c7fc7 100644 --- a/mach/thread_act.defs +++ b/mach/thread_act.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/vm_map.defs b/mach/vm_map.defs index 36aa954..eb67a67 100644 --- a/mach/vm_map.defs +++ b/mach/vm_map.defs @@ -1 +1,25 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/net/addr2ascii.3 b/net/FreeBSD/addr2ascii.3 similarity index 94% rename from net/addr2ascii.3 rename to net/FreeBSD/addr2ascii.3 index 10b1ac7..b72566c 100644 --- a/net/addr2ascii.3 +++ b/net/FreeBSD/addr2ascii.3 @@ -27,7 +27,7 @@ .\" SUCH DAMAGE. .\" .\" $ANA: addr2ascii.3,v 1.1 1996/06/13 18:41:46 wollman Exp $ -.\" $FreeBSD: src/lib/libc/net/addr2ascii.3,v 1.12 2001/10/01 16:08:55 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/addr2ascii.3,v 1.13 2002/12/19 09:40:22 ru Exp $ .\" .Dd June 13, 1996 .Dt ADDR2ASCII 3 @@ -87,16 +87,16 @@ function performs the inverse operation to .Fn addr2ascii . In addition to .Fa af , -it takes two parameters, +it takes two arguments, .Fa ascii and .Fa result . The .Fa ascii -parameter is a pointer to the string which is to be converted into +argument is a pointer to the string which is to be converted into binary. The .Fa result -parameter is a pointer to an appropriate network address structure for +argument is a pointer to an appropriate network address structure for the specified family. .Pp The following gives the appropriate structure to use for binary @@ -171,12 +171,12 @@ The .Fn addr2ascii routine was passed a .Fa len -parameter which was inappropriate for the address family given by +argument which was inappropriate for the address family given by .Fa af . .It Bq Er EPROTONOSUPPORT Either routine was passed an .Fa af -parameter other than +argument other than .Dv AF_INET or .Dv AF_LINK . diff --git a/net/FreeBSD/addr2ascii.c b/net/FreeBSD/addr2ascii.c new file mode 100644 index 0000000..708b0f5 --- /dev/null +++ b/net/FreeBSD/addr2ascii.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/FreeBSD/ascii2addr.c b/net/FreeBSD/ascii2addr.c new file mode 100644 index 0000000..bf2263b --- /dev/null +++ b/net/FreeBSD/ascii2addr.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/inet.3 b/net/FreeBSD/inet.3 similarity index 95% rename from net/inet.3 rename to net/FreeBSD/inet.3 index c65d1dc..06f6a85 100644 --- a/net/inet.3 +++ b/net/FreeBSD/inet.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/inet.3,v 1.19 2001/10/01 16:08:55 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/inet.3,v 1.25 2002/09/06 11:23:49 tjr Exp $ .\" .Dd June 17, 1996 .Dt INET 3 @@ -62,9 +62,14 @@ .Ft char * .Fn inet_ntoa "struct in_addr in" .Ft const char * -.Fn inet_ntop "int af" "const void *src" "char *dst" "size_t size" +.Fo inet_ntop +.Fa "int af" +.Fa "const void * restrict src" +.Fa "char * restrict dst" +.Fa "socklen_t size" +.Fc .Ft int -.Fn inet_pton "int af" "const char *src" "void *dst" +.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 @@ -245,7 +250,7 @@ functions conform to Note that .Fn inet_pton does not accept 1-, 2-, or 3-part dotted addresses; all four parts -must be specified. +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 diff --git a/net/inet_addr.c b/net/FreeBSD/inet_addr.c similarity index 66% rename from net/inet_addr.c rename to net/FreeBSD/inet_addr.c index 4aa396d..d53c9ea 100644 --- a/net/inet_addr.c +++ b/net/FreeBSD/inet_addr.c @@ -1,31 +1,11 @@ +/* $KAME: inet_addr.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */ + /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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++ 1983, 1990, 1993 + * - * Copyright (c) 1983, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * + * 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: @@ -36,12 +16,12 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -53,22 +33,51 @@ * LIABILITY, OR TORT (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 + #include #include + #include #include +#include +#include /* - * Ascii internet address interpretation routine. + * ASCII internet address interpretation routine. * The value returned is in network order. */ -u_long +in_addr_t /* XXX should be struct in_addr :( */ inet_addr(cp) - register const char *cp; + const char *cp; { struct in_addr val; @@ -78,7 +87,7 @@ inet_addr(cp) } /* - * Check whether "cp" is a valid ascii representation + * 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 @@ -86,11 +95,11 @@ inet_addr(cp) */ int inet_aton(cp, addr) - register const char *cp; + const char *cp; struct in_addr *addr; { u_long parts[4]; - u_int32_t val; + in_addr_t val; char *c; char *endptr; int gotend, n; @@ -180,3 +189,12 @@ inet_aton(cp, addr) 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.c b/net/FreeBSD/inet_lnaof.c similarity index 67% rename from net/inet_lnaof.c rename to net/FreeBSD/inet_lnaof.c index ba841b9..d107b27 100644 --- a/net/inet_lnaof.c +++ b/net/FreeBSD/inet_lnaof.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -65,11 +46,11 @@ * internet address; handles class a/b/c network * number formats. */ -u_long +in_addr_t inet_lnaof(in) struct in_addr in; { - register u_long i = ntohl(in.s_addr); + in_addr_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return ((i)&IN_CLASSA_HOST); @@ -78,3 +59,10 @@ inet_lnaof(in) 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.c b/net/FreeBSD/inet_makeaddr.c similarity index 69% rename from net/inet_makeaddr.c rename to net/FreeBSD/inet_makeaddr.c index 08e61ca..27544e7 100644 --- a/net/inet_makeaddr.c +++ b/net/FreeBSD/inet_makeaddr.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -66,9 +47,9 @@ */ struct in_addr inet_makeaddr(net, host) - u_long net, host; + in_addr_t net, host; { - u_long addr; + in_addr_t addr; if (net < 128) addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); @@ -81,3 +62,10 @@ inet_makeaddr(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/FreeBSD/inet_net.3 similarity index 98% rename from net/inet_net.3 rename to net/FreeBSD/inet_net.3 index 1d43bcc..220075f 100644 --- a/net/inet_net.3 +++ b/net/FreeBSD/inet_net.3 @@ -34,7 +34,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/net/inet_net.3,v 1.1 2001/08/31 10:54:44 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/inet_net.3,v 1.2 2002/12/19 09:40:22 ru Exp $ .\" .Dd June 18, 1997 .Dt INET_NET 3 @@ -61,7 +61,9 @@ function converts an Internet network number from network format (usually a .Vt "struct in_addr" or some other binary form, in network byte order) to CIDR presentation format (suitable for external display purposes). +The .Fa bits +argument is the number of bits in .Fa src that are the network number. @@ -90,7 +92,9 @@ The only value for .Fa af currently supported is .Dv AF_INET . +The .Fa size +argument is the size of the result buffer .Fa dst . .Pp diff --git a/net/FreeBSD/inet_net_ntop.c b/net/FreeBSD/inet_net_ntop.c new file mode 100644 index 0000000..b97428a --- /dev/null +++ b/net/FreeBSD/inet_net_ntop.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/FreeBSD/inet_net_pton.c b/net/FreeBSD/inet_net_pton.c new file mode 100644 index 0000000..f2aebcc --- /dev/null +++ b/net/FreeBSD/inet_net_pton.c @@ -0,0 +1,214 @@ +/* + * 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.8 2002/03/22 21:52:29 obrien Exp $"); + +#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; + + ch = *src++; + if (ch == '0' && (src[0] == 'x' || src[0] == 'X') + && isascii(src[1]) && isxdigit(src[1])) { + /* 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(ch)) { + if (isupper(ch)) + ch = tolower(ch); + 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(ch)) { + /* 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(ch)); + if (size-- <= 0) + goto emsgsize; + *dst++ = (u_char) tmp; + if (ch == '\0' || ch == '/') + break; + if (ch != '.') + goto enoent; + ch = *src++; + if (!isascii(ch) || !isdigit(ch)) + goto enoent; + } + } else + goto enoent; + + bits = -1; + if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && 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(ch)); + 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 >= 8 && 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/FreeBSD/inet_neta.c b/net/FreeBSD/inet_neta.c new file mode 100644 index 0000000..43b4af1 --- /dev/null +++ b/net/FreeBSD/inet_neta.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.c b/net/FreeBSD/inet_netof.c similarity index 67% rename from net/inet_netof.c rename to net/FreeBSD/inet_netof.c index e2cd051..1f829a4 100644 --- a/net/inet_netof.c +++ b/net/FreeBSD/inet_netof.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -64,11 +45,11 @@ * Return the network number from an internet * address; handles class a/b/c network #'s. */ -u_long +in_addr_t inet_netof(in) struct in_addr in; { - register u_long i = ntohl(in.s_addr); + in_addr_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); @@ -77,3 +58,10 @@ inet_netof(in) 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.c b/net/FreeBSD/inet_network.c similarity index 64% rename from net/inet_network.c rename to net/FreeBSD/inet_network.c index 7e743ca..92ff831 100644 --- a/net/inet_network.c +++ b/net/FreeBSD/inet_network.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 #include @@ -66,14 +47,14 @@ * The library routines call this routine to interpret * network numbers. */ -u_long +in_addr_t inet_network(cp) - register const char *cp; + const char *cp; { - register u_long val, base, n; - register char c; - u_long parts[4], *pp = parts; - register int i; + in_addr_t val, base, n; + char c; + in_addr_t parts[4], *pp = parts; + int i; again: val = 0; base = 10; @@ -81,34 +62,39 @@ again: base = 8, cp++; if (*cp == 'x' || *cp == 'X') base = 16, cp++; - while (c = *cp) { - if (isdigit(c)) { + while ((c = *cp) != 0) { + if (isdigit((unsigned char)c)) { val = (val * base) + (c - '0'); cp++; continue; } - if (base == 16 && isxdigit(c)) { - val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); + if (base == 16 && isxdigit((unsigned char)c)) { + val = (val << 4) + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); cp++; continue; } break; } if (*cp == '.') { - if (pp >= parts + 4) + if (pp >= parts + 3) return (INADDR_NONE); *pp++ = val, cp++; goto again; } - if (*cp && !isspace(*cp)) + if (*cp && !isspace((unsigned char)*cp)) return (INADDR_NONE); *pp++ = val; n = pp - parts; - if (n > 4) - return (INADDR_NONE); 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.c b/net/FreeBSD/inet_ntoa.c similarity index 62% rename from net/inet_ntoa.c rename to net/FreeBSD/inet_ntoa.c index 0c13d8e..326a76a 100644 --- a/net/inet_ntoa.c +++ b/net/FreeBSD/inet_ntoa.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,26 +31,37 @@ * 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 $"); -/* - * Convert network-format internet address - * to base 256 d.d.d.d representation. - */ #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 b[18]; - register char *p; + static char ret[18]; - p = (char *)∈ -#define UC(b) (((int)b)&0xff) - (void)snprintf(b, sizeof(b), - "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); - return (b); + 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.3 b/net/FreeBSD/linkaddr.3 similarity index 97% rename from net/linkaddr.3 rename to net/FreeBSD/linkaddr.3 index 1d66463..e80d4fa 100644 --- a/net/linkaddr.3 +++ b/net/FreeBSD/linkaddr.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)linkaddr.3 8.1 (Berkeley) 7/28/93 -.\" $FreeBSD: src/lib/libc/net/linkaddr.3,v 1.12 2001/10/01 16:08:56 ru Exp $ +.\" $FreeBSD: src/lib/libc/net/linkaddr.3,v 1.13 2002/12/18 12:45:09 ru Exp $ .\" .Dd June 17, 1996 .Dt LINK_ADDR 3 @@ -102,9 +102,13 @@ The direct use of these functions is deprecated in favor of the interface; however, portable programs cannot rely on the latter as it is not yet widely implemented. .Sh RETURN VALUES +The .Fn link_ntoa +function always returns a null terminated string. +The .Fn link_addr +function has no return value. (See .Sx BUGS . ) diff --git a/net/linkaddr.c b/net/FreeBSD/linkaddr.c similarity index 74% rename from net/linkaddr.c rename to net/FreeBSD/linkaddr.c index baddc5e..0161558 100644 --- a/net/linkaddr.c +++ b/net/FreeBSD/linkaddr.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 @@ -74,12 +55,12 @@ void link_addr(addr, sdl) - register const char *addr; - register struct sockaddr_dl *sdl; + const char *addr; + struct sockaddr_dl *sdl; { - register char *cp = sdl->sdl_data; + char *cp = sdl->sdl_data; char *cplim = sdl->sdl_len + (char *)sdl; - register int byte = 0, state = NAMING, new; + int byte = 0, state = NAMING, new; bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); sdl->sdl_family = AF_LINK; @@ -133,7 +114,7 @@ link_addr(addr, sdl) break; } break; - } while (cp < cplim); + } while (cp < cplim); sdl->sdl_alen = cp - LLADDR(sdl); new = cp - (char *)sdl; if (new > sizeof(*sdl)) @@ -145,12 +126,12 @@ static char hexlist[] = "0123456789abcdef"; char * link_ntoa(sdl) - register const struct sockaddr_dl *sdl; + const struct sockaddr_dl *sdl; { static char obuf[64]; - register char *out = obuf; - register int i; - register u_char *in = (u_char *)LLADDR(sdl); + char *out = obuf; + int i; + u_char *in = (u_char *)LLADDR(sdl); u_char *inlim = in + sdl->sdl_alen; int firsttime = 1; diff --git a/net/FreeBSD/nsap_addr.c b/net/FreeBSD/nsap_addr.c new file mode 100644 index 0000000..8fc9d26 --- /dev/null +++ b/net/FreeBSD/nsap_addr.c @@ -0,0 +1,113 @@ +/* + * 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 +#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; + + while ((c = *ascii++) != '\0' && len < (u_int)maxlen) { + if (c == '.' || c == '+' || c == '/') + continue; + if (!isascii(c)) + return (0); + if (islower(c)) + c = toupper(c); + if (isxdigit(c)) { + nib = xtob(c); + c = *ascii++; + if (c != '\0') { + c = toupper(c); + if (isxdigit(c)) { + *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[255*3]; + char *start; + + 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/FreeBSD/nsap_addr.c.patch b/net/FreeBSD/nsap_addr.c.patch new file mode 100644 index 0000000..3200248 --- /dev/null +++ b/net/FreeBSD/nsap_addr.c.patch @@ -0,0 +1,26 @@ +--- nsap_addr.c.orig Fri Mar 22 13:52:29 2002 ++++ nsap_addr.c Sat May 3 14:17:44 2003 +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + static char + xtob(c) +@@ -78,9 +79,14 @@ + { + int nib; + int i; +- static char tmpbuf[255*3]; ++ static char *tmpbuf = NULL; + char *start; + ++ if (tmpbuf == NULL) { ++ tmpbuf = malloc(255*3); ++ if (tmpbuf == NULL) ++ return NULL; ++ } + if (ascii) + start = ascii; + else { diff --git a/net/recv.c b/net/FreeBSD/recv.c similarity index 63% rename from net/recv.c rename to net/FreeBSD/recv.c index 06320e1..ee3509e 100644 --- a/net/recv.c +++ b/net/FreeBSD/recv.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,15 +31,24 @@ * 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" -ssize_t recv(s, buf, len, flags) +ssize_t +recv(s, buf, len, flags) int s, flags; size_t len; void *buf; { - return (recvfrom(s, buf, len, flags, NULL, 0)); + return (_recvfrom(s, buf, len, flags, NULL, 0)); } diff --git a/compat-43/send.c b/net/FreeBSD/send.c similarity index 64% rename from compat-43/send.c rename to net/FreeBSD/send.c index 772f8f0..8874f46 100644 --- a/compat-43/send.c +++ b/net/FreeBSD/send.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,10 +31,18 @@ * 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" ssize_t send(s, msg, len, flags) @@ -66,5 +50,5 @@ send(s, msg, len, flags) size_t len; const void *msg; { - return (sendto(s, msg, len, flags, NULL, 0)); + return (_sendto(s, msg, len, flags, NULL, 0)); } diff --git a/net/Makefile.inc b/net/Makefile.inc index 7fe1474..694bbe3 100644 --- a/net/Makefile.inc +++ b/net/Makefile.inc @@ -4,35 +4,26 @@ # machine-independent net sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/net ${.CURDIR}/net -SRCS+= inet_addr.c inet_netof.c \ - inet_lnaof.c inet_network.c linkaddr.c nsap_addr.c \ - inet_makeaddr.c inet_ntoa.c recv.c - +.include "Makefile.fbsd_begin" +FBSDSRCS= 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 +.include "Makefile.fbsd_end" CFLAGS+=-DINET6 -I${.OBJDIR} -YFLAGS+=-p_nsyy -LFLAGS+=-P_nsyy - -CLEANFILES+=nsparser.c nslexer.c nsparser.h - -nsparser.h: nsparser.c - mv y.tab.h ${.TARGET} - -nslexer.c: nslexer.l nsparser.h - ${LEX} ${LFLAGS} -o/dev/stdout ${.IMPSRC} | \ - sed -e '/YY_BUF_SIZE/s/16384/1024/' >${.TARGET} - # machine-dependent net sources .if exists(${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc) .include "${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc" .endif .if ${LIB} == "c" -MAN3+= addr2ascii.3 byteorder.3 ethers.3 hesiod.3 \ - inet.3 inet_net.3 \ - nsdispatch.3 rcmdsh.3 resolver.3 -# not installed: iso_addr.3 ns.3 +MAN3+= byteorder.3 ethers.3 hesiod.3 \ + rcmdsh.3 resolver.3 +.include "Makefile.fbsd_begin" +FBSDMAN3= addr2ascii.3 inet.3 inet_net.3 linkaddr.3 +.include "Makefile.fbsd_end" MLINKS+=addr2ascii.3 ascii2addr.3 MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ @@ -45,7 +36,7 @@ MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.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+=ns.3 ns_addr.3 ns.3 ns_ntoa.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 \ diff --git a/net/getaddrinfo.3 b/net/getaddrinfo.3 deleted file mode 100644 index 1ae9e9a..0000000 --- a/net/getaddrinfo.3 +++ /dev/null @@ -1,619 +0,0 @@ -.\" $FreeBSD: src/lib/libc/net/getaddrinfo.3,v 1.17 2001/10/01 16:08:55 ru Exp $ -.\" $KAME: getaddrinfo.3,v 1.22 2000/08/09 21:16:17 itojun Exp $ -.\" -.\" Copyright (c) 1983, 1987, 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: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95 -.\" -.Dd May 25, 1995 -.Dt GETADDRINFO 3 -.Os -.\" -.Sh NAME -.Nm getaddrinfo , -.Nm freeaddrinfo , -.Nm gai_strerror -.Nd nodename-to-address translation in protocol-independent manner -.\" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/socket.h -.In netdb.h -.Ft int -.Fn getaddrinfo "const char *nodename" "const char *servname" \ -"const struct addrinfo *hints" "struct addrinfo **res" -.Ft void -.Fn freeaddrinfo "struct addrinfo *ai" -.Ft "char *" -.Fn gai_strerror "int ecode" -.\" -.Sh DESCRIPTION -The -.Fn getaddrinfo -function is defined for protocol-independent nodename-to-address translation. -It performs the functionality of -.Xr gethostbyname 3 -and -.Xr getservbyname 3 , -but in a more sophisticated manner. -.Pp -The -.Li addrinfo -structure is defined as a result of including the -.Aq Pa netdb.h -header: -.Bd -literal -offset -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for nodename */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -.Ed -.Pp -The -.Fa nodename -and -.Fa servname -arguments are pointers to null-terminated strings or -.Dv NULL . -One or both of these two arguments must be a -.Pf non Dv -NULL -pointer. -In the normal client scenario, both the -.Fa nodename -and -.Fa servname -are specified. -In the normal server scenario, only the -.Fa servname -is specified. -A -.Pf non Dv -NULL -.Fa nodename -string can be either a node name or a numeric host address string -(i.e., a dotted-decimal IPv4 address or an IPv6 hex address). -A -.Pf non Dv -NULL -.Fa servname -string can be either a service name or a decimal port number. -.Pp -The caller can optionally pass an -.Li addrinfo -structure, pointed to by the third argument, -to provide hints concerning the type of socket that the caller supports. -In this -.Fa hints -structure all members other than -.Fa ai_flags , -.Fa ai_family , -.Fa ai_socktype , -and -.Fa ai_protocol -must be zero or a -.Dv NULL -pointer. -A value of -.Dv PF_UNSPEC -for -.Fa ai_family -means the caller will accept any protocol family. -A value of 0 for -.Fa ai_socktype -means the caller will accept any socket type. -A value of 0 for -.Fa ai_protocol -means the caller will accept any protocol. -For example, if the caller handles only TCP and not UDP, then the -.Fa ai_socktype -member of the hints structure should be set to -.Dv SOCK_STREAM -when -.Fn getaddrinfo -is called. -If the caller handles only IPv4 and not IPv6, then the -.Fa ai_family -member of the -.Fa hints -structure should be set to -.Dv PF_INET -when -.Fn getaddrinfo -is called. -If the third argument to -.Fn getaddrinfo -is a -.Dv NULL -pointer, this is the same as if the caller had filled in an -.Li addrinfo -structure initialized to zero with -.Fa ai_family -set to -.Dv PF_UNSPEC . -.Pp -Upon successful return a pointer to a linked list of one or more -.Li addrinfo -structures is returned through the final argument. -The caller can process each -.Li addrinfo -structure in this list by following the -.Fa ai_next -pointer, until a -.Dv NULL -pointer is encountered. -In each returned -.Li addrinfo -structure the three members -.Fa ai_family , -.Fa ai_socktype , -and -.Fa ai_protocol -are the corresponding arguments for a call to the -.Fn socket -function. -In each -.Li addrinfo -structure the -.Fa ai_addr -member points to a filled-in socket address structure whose length is -specified by the -.Fa ai_addrlen -member. -.Pp -If the -.Dv AI_PASSIVE -bit is set in the -.Fa ai_flags -member of the -.Fa hints -structure, then the caller plans to use the returned socket address -structure in a call to -.Fn bind . -In this case, if the -.Fa nodename -argument is a -.Dv NULL -pointer, then the IP address portion of the socket -address structure will be set to -.Dv INADDR_ANY -for an IPv4 address or -.Dv IN6ADDR_ANY_INIT -for an IPv6 address. -.Pp -If the -.Dv AI_PASSIVE -bit is not set in the -.Fa ai_flags -member of the -.Fa hints -structure, then the returned socket address structure will be ready for a -call to -.Fn connect -(for a connection-oriented protocol) -or either -.Fn connect , -.Fn sendto , -or -.Fn sendmsg -(for a connectionless protocol). -In this case, if the -.Fa nodename -argument is a -.Dv NULL -pointer, then the IP address portion of the -socket address structure will be set to the loopback address. -.Pp -If the -.Dv AI_CANONNAME -bit is set in the -.Fa ai_flags -member of the -.Fa hints -structure, then upon successful return the -.Fa ai_canonname -member of the first -.Li addrinfo -structure in the linked list will point to a null-terminated string -containing the canonical name of the specified -.Fa nodename . -.Pp -If the -.Dv AI_NUMERICHOST -bit is set in the -.Fa ai_flags -member of the -.Fa hints -structure, then a -.Pf non Dv -NULL -.Fa nodename -string must be a numeric host address string. -Otherwise an error of -.Dv EAI_NONAME -is returned. -This flag prevents any type of name resolution service (e.g., the DNS) -from being called. -.Pp -The arguments to -.Fn getaddrinfo -must be sufficiently consistent and unambiguous. -Here are some problem cases you may encounter: -.Bl -bullet -.It -.Fn getaddrinfo -will fail if the members in the -.Fa hints -structure are not consistent. -For example, for internet address families, -.Fn getaddrinfo -will fail if you specify -.Dv SOCK_STREAM -to -.Fa ai_socktype -while you specify -.Dv IPPROTO_UDP -to -.Fa ai_protocol . -.It -If you specify a -.Fa servname -which is defined only for certain -.Fa ai_socktype , -.Fn getaddrinfo -will fail because the arguments are not consistent. -For example, -.Fn getaddrinfo -will return an error if you ask for -.Dq Li tftp -service on -.Dv SOCK_STREAM . -.It -For internet address families, if you specify -.Fa servname -while you set -.Fa ai_socktype -to -.Dv SOCK_RAW , -.Fn getaddrinfo -will fail, because service names are not defined for the internet -.Dv SOCK_RAW -space. -.It -If you specify numeric -.Fa servname , -while leaving -.Fa ai_socktype -and -.Fa ai_protocol -unspecified, -.Fn getaddrinfo -will fail. -This is because the numeric -.Fa servname -does not identify any socket type, and -.Fn getaddrinfo -is not allowed to glob the argument in such case. -.El -.Pp -All of the information returned by -.Fn getaddrinfo -is dynamically allocated: -the -.Li addrinfo -structures, the socket address structures, and canonical node name -strings pointed to by the addrinfo structures. -To return this information to the system the function -.Fn freeaddrinfo -is called. -The -.Fa addrinfo -structure pointed to by the -.Fa ai argument -is freed, along with any dynamic storage pointed to by the structure. -This operation is repeated until a -.Dv NULL -.Fa ai_next -pointer is encountered. -.Pp -To aid applications in printing error messages based on the -.Dv EAI_xxx -codes returned by -.Fn getaddrinfo , -.Fn gai_strerror -is defined. -The argument is one of the -.Dv EAI_xxx -values defined earlier and the return value points to a string describing -the error. -If the argument is not one of the -.Dv EAI_xxx -values, the function still returns a pointer to a string whose contents -indicate an unknown error. -.\" -.Sh EXTENSIONS -This implementation supports numeric IPv6 address notation with the -experimental scope identifier. -By appending a percent sign and scope identifier to the address, you -can specify the value of the -.Li sin6_scope_id -field of the socket address. -This makes management of scoped address easier, -and allows cut-and-paste input of scoped addresses. -.Pp -At the moment the code supports only link-local addresses in this format. -The scope identifier is hardcoded to name of hardware interface associated -with the link, -(such as -.Li ne0 ) . -For example, -.Dq Li fe80::1%ne0 , -which means -.Do -.Li fe80::1 -on the link associated with the -.Li ne0 -interface -.Dc . -.Pp -This implementation is still very experimental and non-standard. -The current implementation assumes a one-to-one relationship between -interfaces and links, which is not necessarily true according to the -specification. -.\" -.Sh EXAMPLES -The following code tries to connect to -.Dq Li www.kame.net -service -.Dq Li http . -via stream socket. -It loops through all the addresses available, regardless of the address family. -If the destination resolves to an IPv4 address, it will use an -.Dv AF_INET -socket. -Similarly, if it resolves to IPv6, an -.Dv AF_INET6 -socket is used. -Observe that there is no hardcoded reference to particular address family. -The code works even if -.Fn getaddrinfo -returns addresses that are not IPv4/v6. -.Bd -literal -offset indent -struct addrinfo hints, *res, *res0; -int error; -int s; -const char *cause = NULL; - -memset(&hints, 0, sizeof(hints)); -hints.ai_family = PF_UNSPEC; -hints.ai_socktype = SOCK_STREAM; -error = getaddrinfo("www.kame.net", "http", &hints, &res0); -if (error) { - errx(1, "%s", gai_strerror(error)); - /*NOTREACHED*/ -} -s = -1; -cause = "no addresses"; -errno = EADDRNOTAVAIL; -for (res = res0; res; res = res->ai_next) { - s = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (s < 0) { - cause = "socket"; - continue; - } - - if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { - cause = "connect"; - close(s); - s = -1; - continue; - } - - break; /* okay we got one */ -} -if (s < 0) { - err(1, cause); - /*NOTREACHED*/ -} -freeaddrinfo(res0); -.Ed -.Pp -The following example tries to open a wildcard listening socket onto service -.Dq Li http , -for all the address families available. -.Bd -literal -offset indent -struct addrinfo hints, *res, *res0; -int error; -int s[MAXSOCK]; -int nsock; -const char *cause = NULL; - -memset(&hints, 0, sizeof(hints)); -hints.ai_family = PF_UNSPEC; -hints.ai_socktype = SOCK_STREAM; -hints.ai_flags = AI_PASSIVE; -error = getaddrinfo(NULL, "http", &hints, &res0); -if (error) { - errx(1, "%s", gai_strerror(error)); - /*NOTREACHED*/ -} -nsock = 0; -for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) { - s[nsock] = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (s[nsock] < 0) { - cause = "socket"; - continue; - } - - if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) { - cause = "bind"; - close(s[nsock]); - continue; - } - - if (listen(s[nsock], SOMAXCONN) < 0) { - cause = "listen"; - close(s[nsock]); - continue; - } - - nsock++; -} -if (nsock == 0) { - err(1, cause); - /*NOTREACHED*/ -} -freeaddrinfo(res0); -.Ed -.\" -.Sh FILES -.Bl -tag -width /etc/nsswitch.conf -compact -.It Pa /etc/hosts -.It Pa /etc/nsswitch.conf -.It Pa /etc/resolv.conf -.El -.\" -.Sh DIAGNOSTICS -Error return status from -.Fn getaddrinfo -is zero on success and non-zero on errors. -Non-zero error codes are defined in -.Aq Pa netdb.h , -and as follows: -.Pp -.Bl -tag -width EAI_ADDRFAMILY -compact -.It Dv EAI_ADDRFAMILY -Address family for -.Fa nodename -not supported. -.It Dv EAI_AGAIN -Temporary failure in name resolution. -.It Dv EAI_BADFLAGS -Invalid value for -.Fa ai_flags . -.It Dv EAI_FAIL -Non-recoverable failure in name resolution. -.It Dv EAI_FAMILY -.Fa ai_family -not supported. -.It Dv EAI_MEMORY -Memory allocation failure. -.It Dv EAI_NODATA -No address associated with -.Fa nodename . -.It Dv EAI_NONAME -.Fa nodename -nor -.Fa servname -provided, or not known. -.It Dv EAI_SERVICE -.Fa servname -not supported for -.Fa ai_socktype . -.It Dv EAI_SOCKTYPE -.Fa ai_socktype -not supported. -.It Dv EAI_SYSTEM -System error returned in -.Va errno . -.It Dv EAI_BADHINTS -Invalid value for -.Fa hints . -.It Dv EAI_PROTOCOL -Resolved protocol is unknown. -.It Dv EAI_MAX -Unknown error. -.El -.Pp -If called with an appropriate argument, -.Fn gai_strerror -returns a pointer to a string describing the given error code. -If the argument is not one of the -.Dv EAI_xxx -values, the function still returns a pointer to a string whose contents -indicate an unknown error. -.\" -.Sh SEE ALSO -.Xr gethostbyname 3 , -.Xr getnameinfo 3 , -.Xr getservbyname 3 , -.Xr hosts 5 , -.Xr services 5 , -.Xr hostname 7 , -.Xr named 8 -.Pp -.Rs -.%A R. Gilligan -.%A S. Thomson -.%A J. Bound -.%A W. Stevens -.%T Basic Socket Interface Extensions for IPv6 -.%R RFC2553 -.%D March 1999 -.Re -.Rs -.%A Tatsuya Jinmei -.%A Atsushi Onoe -.%T "An Extension of Format for IPv6 Scoped Addresses" -.%R internet draft -.%N draft-ietf-ipngwg-scopedaddr-format-02.txt -.%O work in progress material -.Re -.Rs -.%A Craig Metz -.%T Protocol Independence Using the Sockets API -.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference" -.%D June 2000 -.Re -.\" -.Sh HISTORY -The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit. -.\" -.Sh STANDARDS -The -.Fn getaddrinfo -function is defined in -.St -p1003.1g-2000 , -and documented in -.Dq Basic Socket Interface Extensions for IPv6 -(RFC2553). -.\" -.Sh BUGS -The current implementation is not thread-safe. -.Pp -The text was shamelessly copied from RFC2553. diff --git a/net/gethostbyname.3 b/net/gethostbyname.3 deleted file mode 100644 index 8efba37..0000000 --- a/net/gethostbyname.3 +++ /dev/null @@ -1,380 +0,0 @@ -.\" Copyright (c) 1983, 1987, 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: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95 -.\" $FreeBSD: src/lib/libc/net/gethostbyname.3,v 1.25 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd May 25, 1995 -.Dt GETHOSTBYNAME 3 -.Os -.Sh NAME -.Nm gethostbyname , -.Nm gethostbyname2 , -.Nm gethostbyaddr , -.Nm gethostent , -.Nm sethostent , -.Nm endhostent , -.Nm herror , -.Nm hstrerror -.Nd get network host entry -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netdb.h -.Vt extern int h_errno ; -.Ft struct hostent * -.Fn gethostbyname "const char *name" -.Ft struct hostent * -.Fn gethostbyname2 "const char *name" "int af" -.Ft struct hostent * -.Fn gethostbyaddr "const char *addr" "int len" "int type" -.Ft struct hostent * -.Fn gethostent void -.Ft void -.Fn sethostent "int stayopen" -.Ft void -.Fn endhostent void -.Ft void -.Fn herror "const char *string" -.Ft const char * -.Fn hstrerror "int err" -.Sh DESCRIPTION -.Bf -symbolic -The -.Xr getaddrinfo 3 -and -.Xr getnameinfo 3 -functions are preferred over the -.Fn gethostbyname , -.Fn gethostbyname2 , -and -.Fn gethostbyaddr -functions. -.Ef -.Pp -The -.Fn gethostbyname , -.Fn gethostbyname2 -and -.Fn gethostbyaddr -functions -each return a pointer to an object with the -following structure describing an internet host -referenced by name or by address, respectively. -.Pp -The -.Fa name -parameter passed to -.Fn gethostbyname -or -.Fn gethostbyname2 -should point to a -.Dv NUL Ns -terminated -hostname. -The -.Fa addr -parameter passed to -.Fn gethostbyaddr -should point to an address which is -.Fa len -bytes long, -in binary form -(i.e. not an IP address in human readable -.Tn ASCII -form). -The -.Fa type -parameter specifies the address family -(e.g.\& -.Dv AF_INET , AF_INET6 , -etc.) of this address. -.Pp -The structure returned contains either the information obtained from the name -server, -.Xr named 8 , -broken-out fields from a line in -.Pa /etc/hosts , -or database entries supplied by the -.Xr yp 4 -system. -The order of the lookups is controlled by the -.Sq hosts -entry in -.Xr nsswitch.conf 5 . -.Bd -literal -struct hostent { - char *h_name; /* official name of host */ - char **h_aliases; /* alias list */ - int h_addrtype; /* host address type */ - int h_length; /* length of address */ - char **h_addr_list; /* list of addresses from name server */ -}; -#define h_addr h_addr_list[0] /* address, for backward compatibility */ -.Ed -.Pp -The members of this structure are: -.Bl -tag -width h_addr_list -.It Va h_name -Official name of the host. -.It Va h_aliases -A -.Dv NULL Ns -terminated -array of alternate names for the host. -.It Va h_addrtype -The type of address being returned; usually -.Dv AF_INET . -.It Va h_length -The length, in bytes, of the address. -.It Va h_addr_list -A -.Dv NULL Ns -terminated -array of network addresses for the host. -Host addresses are returned in network byte order. -.It Va h_addr -The first address in -.Va h_addr_list ; -this is for backward compatibility. -.El -.Pp -When using the nameserver, -.Fn gethostbyname -and -.Fn gethostbyname2 -will search for the named host in the current domain and its parents -unless the name ends in a dot. -If the name contains no dot, and if the environment variable -.Dq Ev HOSTALIASES -contains the name of an alias file, the alias file will first be searched -for an alias matching the input name. -See -.Xr hostname 7 -for the domain search procedure and the alias file format. -.Pp -The -.Fn gethostbyname2 -function is an evolution of -.Fn gethostbyname -which is intended to allow lookups in address families other than -.Dv AF_INET , -for example -.Dv AF_INET6 . -.Pp -The -.Fn sethostent -function -may be used to request the use of a connected -.Tn TCP -socket for queries. -If the -.Fa stayopen -flag is non-zero, -this sets the option to send all queries to the name server using -.Tn TCP -and to retain the connection after each call to -.Fn gethostbyname , -.Fn gethostbyname2 -or -.Fn gethostbyaddr . -Otherwise, queries are performed using -.Tn UDP -datagrams. -.Pp -The -.Fn endhostent -function -closes the -.Tn TCP -connection. -.Pp -The -.Fn herror -function writes a message to the diagnostic output consisting of the -string parameter -.Fa s , -the constant string -.Qq Li ":\ " , -and a message corresponding to the value of -.Va h_errno . -.Pp -The -.Fn hstrerror -function returns a string which is the message text corresponding to the -value of the -.Fa err -parameter. -.Sh FILES -.Bl -tag -width /etc/nsswitch.conf -compact -.It Pa /etc/hosts -.It Pa /etc/nsswitch.conf -.It Pa /etc/resolv.conf -.El -.Sh EXAMPLES -Print out the hostname associated with a specific IP address: -.Bd -literal -offset indent -const char *ipstr = "127.0.0.1"; -struct in_addr ip; -struct hostent *hp; - -if (!inet_aton(ipstr, &ip)) - errx(1, "can't parse IP address %s", ipstr); - -if ((hp = gethostbyaddr((const char *)&ip, - sizeof ip, AF_INET)) == NULL) - errx(1, "no name associated with %s", ipstr); - -printf("name associated with %s is %s\en", ipstr, hp->h_name); -.Ed -.Sh DIAGNOSTICS -Error return status from -.Fn gethostbyname , -.Fn gethostbyname2 -and -.Fn gethostbyaddr -is indicated by return of a -.Dv NULL -pointer. -The external integer -.Va h_errno -may then be checked to see whether this is a temporary failure -or an invalid or unknown host. -The routine -.Fn herror -can be used to print an error message describing the failure. -If its argument -.Fa string -is -.Pf non- Dv NULL , -it is printed, followed by a colon and a space. -The error message is printed with a trailing newline. -.Pp -The variable -.Va h_errno -can have the following values: -.Bl -tag -width HOST_NOT_FOUND -.It Dv HOST_NOT_FOUND -No such host is known. -.It Dv TRY_AGAIN -This is usually a temporary error -and means that the local server did not receive -a response from an authoritative server. -A retry at some later time may succeed. -.It Dv NO_RECOVERY -Some unexpected server failure was encountered. -This is a non-recoverable error. -.It Dv NO_DATA -The requested name is valid but does not have an IP address; -this is not a temporary error. -This means that the name is known to the name server but there is no address -associated with this name. -Another type of request to the name server using this domain name -will result in an answer; -for example, a mail-forwarder may be registered for this domain. -.El -.Sh SEE ALSO -.Xr getaddrinfo 3 , -.Xr getnameinfo 3 , -.Xr inet_aton 3 , -.Xr resolver 3 , -.Xr hosts 5 , -.Xr hostname 7 , -.Xr named 8 -.Sh CAVEAT -The -.Fn gethostent -function -is defined, and -.Fn sethostent -and -.Fn endhostent -are redefined, -when -.Xr libc 3 -is built to use only the routines to lookup in -.Pa /etc/hosts -and not the name server. -.Pp -The -.Fn gethostent -function -reads the next line of -.Pa /etc/hosts , -opening the file if necessary. -.Pp -The -.Fn sethostent -function -opens and/or rewinds the file -.Pa /etc/hosts . -If the -.Fa stayopen -argument is non-zero, -the file will not be closed after each call to -.Fn gethostbyname , -.Fn gethostbyname2 -or -.Fn gethostbyaddr . -.Pp -The -.Fn endhostent -function -closes the file. -.Sh HISTORY -The -.Fn herror -function appeared in -.Bx 4.3 . -The -.Fn endhostent , -.Fn gethostbyaddr , -.Fn gethostbyname , -.Fn gethostent , -and -.Fn sethostent -functions appeared in -.Bx 4.2 . -The -.Fn gethostbyname2 -function first appeared in -.Tn BIND -version 4.9.4. -.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. -Only the Internet -address format is currently understood. -.Pp -.Fn gethostbyname2 -cannot perform -.Dv AF_INET6 -lookups over NIS. -.Xr getaddrinfo 3 -must be used instead. diff --git a/net/getifaddrs.3 b/net/getifaddrs.3 deleted file mode 100644 index 47e5004..0000000 --- a/net/getifaddrs.3 +++ /dev/null @@ -1,164 +0,0 @@ -.\" $FreeBSD: src/lib/libc/net/getifaddrs.3,v 1.6 2001/10/01 16:08:55 ru Exp $ -.\" $KAME: getifaddrs.3,v 1.4 2000/05/17 14:13:14 itojun Exp $ -.\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp -.\" -.\" Copyright (c) 1995, 1999 -.\" Berkeley Software Design, 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (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 October 12, 1995 -.Dt GETIFADDRS 3 -.Os -.Sh NAME -.Nm getifaddrs -.Nd get interface addresses -.Sh SYNOPSIS -.In sys/types.h -.In sys/socket.h -.In ifaddrs.h -.Ft int -.Fn getifaddrs "struct ifaddrs **ifap" -.Ft void -.Fn freeifaddrs "struct ifaddrs *ifp" -.Sh DESCRIPTION -The -.Fn getifaddrs -function stores a reference to a linked list of the network interfaces -on the local machine in the memory referenced by -.Fa ifap . -The list consists of -.Nm ifaddrs -structures, as defined in the include file -.Aq Pa ifaddrs.h . -The -.Nm ifaddrs -structure contains at least the following entries: -.Bd -literal - struct ifaddrs *ifa_next; /* Pointer to next struct */ - char *ifa_name; /* Interface name */ - u_int ifa_flags; /* Interface flags */ - struct sockaddr *ifa_addr; /* Interface address */ - struct sockaddr *ifa_netmask; /* Interface netmask */ - struct sockaddr *ifa_broadaddr; /* Interface broadcast address */ - struct sockaddr *ifa_dstaddr; /* P2P interface destination */ - void *ifa_data; /* Address specific data */ -.Ed -.Pp -The -.Li ifa_next -field contains a pointer to the next structure on the list. -This field is -.Dv NULL -in last structure on the list. -.Pp -The -.Li ifa_name -field contains the interface name. -.Pp -The -.Li ifa_flags -field contains the interface flags, as set by -.Xr ifconfig 8 -utility. -.Pp -The -.Li ifa_addr -field references either the address of the interface or the link level -address of the interface, if one exists, otherwise it is NULL. -(The -.Li sa_family -field of the -.Li ifa_addr -field should be consulted to determine the format of the -.Li ifa_addr -address.) -.Pp -The -.Li ifa_netmask -field references the netmask associated with -.Li ifa_addr , -if one is set, otherwise it is NULL. -.Pp -The -.Li ifa_broadaddr -field, -which should only be referenced for non-P2P interfaces, -references the broadcast address associated with -.Li ifa_addr , -if one exists, otherwise it is NULL. -.Pp -The -.Li ifa_dstaddr -field references the destination address on a P2P interface, -if one exists, otherwise it is NULL. -.Pp -The -.Li ifa_data -field references address family specific data. For -.Dv AF_LINK -addresses it contains a pointer to the -.Fa struct if_data -(as defined in include file -.Aq Pa net/if.h ) -which contains various interface attributes and statistics. -For all other address families, it contains a pointer to the -.Fa struct ifa_data -(as defined in include file -.Aq Pa net/if.h ) -which contains per-address interface statistics. -.Pp -The data returned by -.Fn getifaddrs -is dynamically allocated and should be freed using -.Fn freeifaddrs -when no longer needed. -.Sh RETURN VALUES -.Rv -std getifaddrs -.Sh ERRORS -The -.Fn getifaddrs -may fail and set -.Va errno -for any of the errors specified for the library routines -.Xr ioctl 2 , -.Xr socket 2 , -.Xr malloc 3 -or -.Xr sysctl 3 . -.Sh BUGS -If both -.Aq Pa net/if.h -and -.Aq Pa ifaddrs.h -are being included, -.Aq Pa net/if.h -.Em must -be included before -.Aq Pa ifaddrs.h . -.Sh SEE ALSO -.Xr ioctl 2 , -.Xr socket 2 , -.Xr sysctl 3 , -.Xr networking 4 , -.Xr ifconfig 8 -.Sh HISTORY -The -.Nm -implementation first appeared in BSDi -.Bsx . diff --git a/net/getipnodebyname.3 b/net/getipnodebyname.3 deleted file mode 100644 index 5b8ea1e..0000000 --- a/net/getipnodebyname.3 +++ /dev/null @@ -1,461 +0,0 @@ -.\" $FreeBSD: src/lib/libc/net/getipnodebyname.3,v 1.8 2001/10/01 16:08:55 ru Exp $ -.\" $KAME: getipnodebyname.3,v 1.6 2000/08/09 21:16:17 itojun Exp $ -.\" -.\" Copyright (c) 1983, 1987, 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: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95 -.\" -.Dd May 25, 1995 -.Dt GETIPNODEBYNAME 3 -.Os -.\" -.Sh NAME -.Nm getipnodebyname , -.Nm getipnodebyaddr , -.Nm freehostent -.Nd nodename-to-address and address-to-nodename translation -.\" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/socket.h -.In netdb.h -.Ft "struct hostent *" -.Fn getipnodebyname "const char *name" "int af" "int flags" "int *error_num" -.Ft "struct hostent *" -.Fn getipnodebyaddr "const void *src" "size_t len" "int af" "int *error_num" -.Ft void -.Fn freehostent "struct hostent *ptr" -.\" -.Sh DESCRIPTION -.Fn getipnodebyname -and -.Fn getipnodebyaddr -functions are very similar to -.Xr gethostbyname 3 , -.Xr gethostbyname2 3 -and -.Xr gethostbyaddr 3 . -The functions cover all the functionalities provided by the older ones, -and provide better interface to programmers. -The functions require additional arguments, -.Ar af , -and -.Ar flags , -for specifying address family and operation mode. -The additional arguments allow programmer to get address for a nodename, -for specific address family -(such as -.Dv AF_INET -or -.Dv AF_INET6 ) . -The functions also require an additional pointer argument, -.Ar error_num -to return the appropriate error code, -to support thread safe error code returns. -.Pp -The type and usage of the return value, -.Li "struct hostent" -is described in -.Xr gethostbyname 3 . -.Pp -For -.Fn getipnodebyname , -the -.Ar name -argument can be either a node name or a numeric address -string -(i.e., a dotted-decimal IPv4 address or an IPv6 hex address). -The -.Ar af -argument specifies the address family, either -.Dv AF_INET -or -.Dv AF_INET6 . -The -.Ar flags -argument specifies the types of addresses that are searched for, -and the types of addresses that are returned. -We note that a special flags value of -.Dv AI_DEFAULT -(defined below) -should handle most applications. -That is, porting simple applications to use IPv6 replaces the call -.Bd -literal -offset - hptr = gethostbyname(name); -.Ed -.Pp -with -.Bd -literal -offset - hptr = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num); -.Ed -.Pp -Applications desiring finer control over the types of addresses -searched for and returned, can specify other combinations of the -.Ar flags -argument. -.Pp -A -.Ar flags -of -.Li 0 -implies a strict interpretation of the -.Ar af -argument: -.Bl -bullet -.It -If -.Ar flags -is 0 and -.Ar af -is -.Dv AF_INET , -then the caller wants only IPv4 addresses. -A query is made for -.Li A -records. -If successful, the IPv4 addresses are returned and the -.Li h_length -member of the -.Li hostent -structure will be 4, else the function returns a -.Dv NULL -pointer. -.It -If -.Ar flags -is 0 and if -.Ar af -is -.Li AF_INET6 , -then the caller wants only IPv6 addresses. -A query is made for -.Li AAAA -records. -If successful, the IPv6 addresses are returned and the -.Li h_length -member of the -.Li hostent -structure will be 16, else the function returns a -.Dv NULL -pointer. -.El -.Pp -Other constants can be logically-ORed into the -.Ar flags -argument, to modify the behavior of the function. -.Bl -bullet -.It -If the -.Dv AI_V4MAPPED -flag is specified along with an -.Ar af -of -.Dv AF_INET6 , -then the caller will accept IPv4-mapped IPv6 addresses. -That is, if no -.Li AAAA -records are found then a query is made for -.Li A -records and any found are returned as IPv4-mapped IPv6 addresses -.Li ( h_length -will be 16). -The -.Dv AI_V4MAPPED -flag is ignored unless -.Ar af -equals -.Dv AF_INET6 . -.It -The -.Dv AI_V4MAPPED_CFG -flag is exact same as the -.Dv AI_V4MAPPED -flag only if the kernel supports IPv4-mapped IPv6 address. -.It -If the -.Dv AI_ALL -flag is used in conjunction with the -.Dv AI_V4MAPPED -flag, and only used with the IPv6 address family. -When -.Dv AI_ALL -is logically or'd with -.Dv AI_V4MAPPED -flag then the caller wants all addresses: IPv6 and IPv4-mapped IPv6. -A query is first made for -.Li AAAA -records and if successful, the -IPv6 addresses are returned. Another query is then made for -.Li A -records and any found are returned as IPv4-mapped IPv6 addresses. -.Li h_length -will be 16. Only if both queries fail does the function -return a -.Dv NULL -pointer. This flag is ignored unless af equals -AF_INET6. If both -.Dv AI_ALL -and -.Dv AI_V4MAPPED -are specified, -.Dv AI_ALL -takes precedence. -.It -The -.Dv AI_ADDRCONFIG -flag specifies that a query for -.Li AAAA -records -should occur only if the node has at least one IPv6 source -address configured and a query for -.Li A -records should occur only if the node has at least one IPv4 source address -configured. -.Pp -For example, if the node has no IPv6 source addresses configured, -and -.Ar af -equals AF_INET6, and the node name being looked up has both -.Li AAAA -and -.Li A -records, then: -(a) if only -.Dv AI_ADDRCONFIG -is -specified, the function returns a -.Dv NULL -pointer; -(b) if -.Dv AI_ADDRCONFIG -| -.Dv AI_V4MAPPED -is specified, the -.Li A -records are returned as IPv4-mapped IPv6 addresses; -.El -.Pp -The special flags value of -.Dv AI_DEFAULT -is defined as -.Bd -literal -offset - #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) -.Ed -.Pp -We noted that the -.Fn getipnodebyname -function must allow the -.Ar name -argument to be either a node name or a literal address string -(i.e., a dotted-decimal IPv4 address or an IPv6 hex address). -This saves applications from having to call -.Xr inet_pton 3 -to handle literal address strings. -When the -.Ar name -argument is a literal address string, -the -.Ar flags -argument is always ignored. -.Pp -There are four scenarios based on the type of literal address string -and the value of the -.Ar af -argument. -The two simple cases are when -.Ar name -is a dotted-decimal IPv4 address and -.Ar af -equals -.Dv AF_INET , -or when -.Ar name -is an IPv6 hex address and -.Ar af -equals -.Dv AF_INET6 . -The members of the -returned hostent structure are: -.Li h_name -points to a copy of the -.Ar name -argument, -.Li h_aliases -is a -.Dv NULL -pointer, -.Li h_addrtype -is a copy of the -.Ar af -argument, -.Li h_length -is either 4 -(for -.Dv AF_INET ) -or 16 -(for -.Dv AF_INET6 ) , -.Li h_addr_list[0] -is a pointer to the 4-byte or 16-byte binary address, -and -.Li h_addr_list[1] -is a -.Dv NULL -pointer. -.Pp -When -.Ar name -is a dotted-decimal IPv4 address and -.Ar af -equals -.Dv AF_INET6 , -and -.Dv AI_V4MAPPED -is specified, -an IPv4-mapped IPv6 address is returned: -.Li h_name -points to an IPv6 hex address containing the IPv4-mapped IPv6 address, -.Li h_aliases -is a -.Dv NULL -pointer, -.Li h_addrtype -is -.Dv AF_INET6 , -.Li h_length -is 16, -.Li h_addr_list[0] -is a pointer to the 16-byte binary address, and -.Li h_addr_list[1] -is a -.Dv NULL -pointer. -.Pp -It is an error when -.Ar name -is an IPv6 hex address and -.Ar af -equals -.Dv AF_INET . -The function's return value is a -.Dv NULL -pointer and the value pointed to by -.Ar error_num -equals -.Dv HOST_NOT_FOUND . -.Pp -.Fn getipnodebyaddr -takes almost the same argument as -.Xr gethostbyaddr 3 , -but adds a pointer to return an error number. -Additionally it takes care of IPv4-mapped IPv6 addresses, -and IPv4-compatible IPv6 addresses. -.Pp -.Fn getipnodebyname -and -.Fn getipnodebyaddr -dynamically allocate the structure to be returned to the caller. -.Fn freehostent -reclaims memory region allocated and returned by -.Fn getipnodebyname -or -.Fn getipnodebyaddr . -.\" -.Sh FILES -.Bl -tag -width /etc/nsswitch.conf -compact -.It Pa /etc/hosts -.It Pa /etc/nsswitch.conf -.It Pa /etc/resolv.conf -.El -.\" -.Sh DIAGNOSTICS -.Fn getipnodebyname -and -.Fn getipnodebyaddr -returns -.Dv NULL -on errors. -The integer values pointed to by -.Ar error_num -may then be checked to see whether this is a temporary failure -or an invalid or unknown host. -The meanings of each error code are described in -.Xr gethostbyname 3 . -.\" -.Sh SEE ALSO -.Xr gethostbyaddr 3 , -.Xr gethostbyname 3 , -.Xr hosts 5 , -.Xr nsswitch.conf 5 , -.Xr services 5 , -.Xr hostname 7 , -.Xr named 8 -.Pp -.Rs -.%A R. Gilligan -.%A S. Thomson -.%A J. Bound -.%A W. Stevens -.%T Basic Socket Interface Extensions for IPv6 -.%R RFC2553 -.%D March 1999 -.Re -.\" -.Sh HISTORY -The implementation first appeared in KAME advanced networking kit. -.\" -.Sh STANDARDS -.Fn getipnodebyname -and -.Fn getipnodebyaddr -are documented in -.Dq Basic Socket Interface Extensions for IPv6 -(RFC2553). -.\" -.Sh BUGS -.Fn getipnodebyname -and -.Fn getipnodebyaddr -do not handle scoped IPv6 address properly. -If you use these functions, -your program will not be able to handle scoped IPv6 addresses. -For IPv6 address manipulation, -.Fn getaddrinfo 3 -and -.Fn getnameinfo 3 -are recommended. -.Pp -The current implementation is not thread-safe. -.Pp -The text was shamelessly copied from RFC2553. diff --git a/net/getnameinfo.3 b/net/getnameinfo.3 deleted file mode 100644 index d7afa2f..0000000 --- a/net/getnameinfo.3 +++ /dev/null @@ -1,311 +0,0 @@ -.\" $FreeBSD: src/lib/libc/net/getnameinfo.3,v 1.11 2001/10/01 16:08:55 ru Exp $ -.\" $KAME: getnameinfo.3,v 1.17 2000/08/09 21:16:17 itojun Exp $ -.\" -.\" Copyright (c) 1983, 1987, 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: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95 -.\" -.Dd May 25, 1995 -.Dt GETNAMEINFO 3 -.Os -.\" -.Sh NAME -.Nm getnameinfo -.Nd address-to-nodename translation in protocol-independent manner -.\" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/socket.h -.In netdb.h -.Ft int -.Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" \ -"char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags" -.\" -.Sh DESCRIPTION -The -.Fn getnameinfo -function is defined for protocol-independent address-to-nodename translation. -Its functionality is a reverse conversion of -.Xr getaddrinfo 3 , -and implements similar functionality with -.Xr gethostbyaddr 3 -and -.Xr getservbyport 3 -in more sophisticated manner. -.Pp -This function looks up an IP address and port number provided by the -caller in the DNS and system-specific database, and returns text -strings for both in buffers provided by the caller. -The function indicates successful completion by a zero return value; -a non-zero return value indicates failure. -.Pp -The first argument, -.Fa sa , -points to either a -.Li sockaddr_in -structure (for IPv4) or a -.Li sockaddr_in6 -structure (for IPv6) that holds the IP address and port number. -The -.Fa salen -argument gives the length of the -.Li sockaddr_in -or -.Li sockaddr_in6 -structure. -.Pp -The function returns the nodename associated with the IP address in -the buffer pointed to by the -.Fa host -argument. -The caller provides the size of this buffer via the -.Fa hostlen -argument. -The service name associated with the port number is returned in the buffer -pointed to by -.Fa serv , -and the -.Fa servlen -argument gives the length of this buffer. -The caller specifies not to return either string by providing a zero -value for the -.Fa hostlen -or -.Fa servlen -arguments. -Otherwise, the caller must provide buffers large enough to hold the -nodename and the service name, including the terminating null characters. -.Pp -Unfortunately most systems do not provide constants that specify the -maximum size of either a fully-qualified domain name or a service name. -Therefore to aid the application in allocating buffers for these two -returned strings the following constants are defined in -.Aq Pa netdb.h : -.Bd -literal -offset -#define NI_MAXHOST 1025 -#define NI_MAXSERV 32 -.Ed -.Pp -The first value is actually defined as the constant -.Dv MAXDNAME -in recent versions of BIND's -.Aq Pa arpa/nameser.h -header -(older versions of BIND define this constant to be 256) -and the second is a guess based on the services listed in the current -Assigned Numbers RFC. -.Pp -The final argument is a -.Fa flag -that changes the default actions of this function. -By default the fully-qualified domain name (FQDN) for the host is -looked up in the DNS and returned. -If the flag bit -.Dv NI_NOFQDN -is set, only the nodename portion of the FQDN is returned for local hosts. -.Pp -If the -.Fa flag -bit -.Dv NI_NUMERICHOST -is set, or if the host's name cannot be located in the DNS, -the numeric form of the host's address is returned instead of its name -(e.g., by calling -.Fn inet_ntop -instead of -.Fn getnodebyaddr ) . -If the -.Fa flag -bit -.Dv NI_NAMEREQD -is set, an error is returned if the host's name cannot be located in the DNS. -.Pp -If the flag bit -.Dv NI_NUMERICSERV -is set, the numeric form of the service address is returned -(e.g., its port number) -instead of its name. -The two -.Dv NI_NUMERICxxx -flags are required to support the -.Fl n -flag that many commands provide. -.Pp -A fifth flag bit, -.Dv NI_DGRAM , -specifies that the service is a datagram service, and causes -.Fn getservbyport -to be called with a second argument of -.Dq udp -instead of its default of -.Dq tcp . -This is required for the few ports (512-514) -that have different services for UDP and TCP. -.Pp -These -.Dv NI_xxx -flags are defined in -.Aq Pa netdb.h . -.\" -.Sh EXTENSION -The implementation allows experimental numeric IPv6 address notation with -scope identifier. -IPv6 link-local address will appear as string like -.Dq Li fe80::1%ne0 , -if -.Dv NI_WITHSCOPEID -bit is enabled in -.Ar flags -argument. -Refer to -.Xr getaddrinfo 3 -for the notation. -.\" -.Sh EXAMPLES -The following code tries to get numeric hostname, and service name, -for given socket address. -Observe that there is no hardcoded reference to particular address family. -.Bd -literal -offset indent -struct sockaddr *sa; /* input */ -char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - -if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, - sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { - errx(1, "could not get numeric hostname"); - /*NOTREACHED*/ -} -printf("host=%s, serv=%s\\n", hbuf, sbuf); -.Ed -.Pp -The following version checks if the socket address has reverse address mapping. -.Bd -literal -offset indent -struct sockaddr *sa; /* input */ -char hbuf[NI_MAXHOST]; - -if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, - NI_NAMEREQD)) { - errx(1, "could not resolve hostname"); - /*NOTREACHED*/ -} -printf("host=%s\\n", hbuf); -.Ed -.\" -.Sh FILES -.Bl -tag -width /etc/nsswitch.conf -compact -.It Pa /etc/hosts -.It Pa /etc/nsswitch.conf -.It Pa /etc/resolv.conf -.El -.\" -.Sh DIAGNOSTICS -The function indicates successful completion by a zero return value; -a non-zero return value indicates failure. -Error codes are as below: -.Bl -tag -width Er -.It Bq Er EAI_AGAIN -The name could not be resolved at this time. -Future attempts may succeed. -.It Bq Er EAI_BADFLAGS -The flags had an invalid value. -.It Bq Er EAI_FAIL -A non-recoverable error occurred. -.It Bq Er EAI_FAMILY -The address family was not recognized or the address length was invalid -for the specified family. -.It Bq Er EAI_MEMORY -There was a memory allocation failure. -.It Bq Er EAI_NONAME -The name does not resolve for the supplied parameters. -.Dv NI_NAMEREQD -is set and the host's name cannot be located, -or both nodename and servname were null. -.It Bq Er EAI_SYSTEM -A system error occurred. -The error code can be found in errno. -.El -.\" -.Sh SEE ALSO -.Xr getaddrinfo 3 , -.Xr gethostbyaddr 3 , -.Xr getservbyport 3 , -.Xr hosts 5 , -.Xr services 5 , -.Xr hostname 7 , -.Xr named 8 -.Pp -.Rs -.%A R. Gilligan -.%A S. Thomson -.%A J. Bound -.%A W. Stevens -.%T Basic Socket Interface Extensions for IPv6 -.%R RFC2553 -.%D March 1999 -.Re -.Rs -.%A Tatsuya Jinmei -.%A Atsushi Onoe -.%T "An Extension of Format for IPv6 Scoped Addresses" -.%R internet draft -.%N draft-ietf-ipngwg-scopedaddr-format-02.txt -.%O work in progress material -.Re -.Rs -.%A Craig Metz -.%T Protocol Independence Using the Sockets API -.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference" -.%D June 2000 -.Re -.\" -.Sh HISTORY -The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit. -.\" -.Sh STANDARDS -The -.Fn getaddrinfo -function is defined in -.St -p1003.1g-2000 , -and documented in -.Dq Basic Socket Interface Extensions for IPv6 -(RFC2553). -.\" -.Sh BUGS -The current implementation is not thread-safe. -.Pp -The text was shamelessly copied from RFC2553. -.Pp -The type of the 2nd argument should be -.Li socklen_t -for RFC2553 conformance. -The current code is based on pre-RFC2553 specification. diff --git a/net/getnetent.3 b/net/getnetent.3 deleted file mode 100644 index 7a60a67..0000000 --- a/net/getnetent.3 +++ /dev/null @@ -1,172 +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. -.\" -.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/getnetent.3,v 1.16 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt GETNETENT 3 -.Os -.Sh NAME -.Nm getnetent , -.Nm getnetbyaddr , -.Nm getnetbyname , -.Nm setnetent , -.Nm endnetent -.Nd get network entry -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netdb.h -.Ft struct netent * -.Fn getnetent void -.Ft struct netent * -.Fn getnetbyname "const char *name" -.Ft struct netent * -.Fn getnetbyaddr "unsigned long net" "int type" -.Ft void -.Fn setnetent "int stayopen" -.Ft void -.Fn endnetent void -.Sh DESCRIPTION -The -.Fn getnetent , -.Fn getnetbyname , -and -.Fn getnetbyaddr -functions -each return a pointer to an object with the -following structure describing an internet network. -This structure contains either the information obtained -from the nameserver, -.Xr named 8 , -broken-out fields of a line in the network data base -.Pa /etc/networks , -or entries supplied by the -.Xr yp 4 -system. The order of the lookups is controlled by the -`networks' entry in -.Xr nsswitch.conf 5 . -.Pp -.Bd -literal -offset indent -struct netent { - char *n_name; /* official name of net */ - char **n_aliases; /* alias list */ - int n_addrtype; /* net number type */ - unsigned long n_net; /* net number */ -}; -.Ed -.Pp -The members of this structure are: -.Bl -tag -width n_addrtype -.It Fa n_name -The official name of the network. -.It Fa n_aliases -A zero terminated list of alternate names for the network. -.It Fa n_addrtype -The type of the network number returned; currently only AF_INET. -.It Fa n_net -The network number. Network numbers are returned in machine byte -order. -.El -.Pp -The -.Fn getnetent -function -reads the next line of the file, opening the file if necessary. -.Pp -The -.Fn setnetent -function -opens and rewinds the file. If the -.Fa stayopen -flag is non-zero, -the net data base will not be closed after each call to -.Fn getnetbyname -or -.Fn getnetbyaddr . -.Pp -The -.Fn endnetent -function -closes the file. -.Pp -The -.Fn getnetbyname -function -and -.Fn getnetbyaddr -sequentially search from the beginning -of the file until a matching -net name or -net address and type is found, -or until -.Dv EOF -is encountered. -The -.Fa type -must be -.Dv AF_INET . -Network numbers are supplied in host order. -.Sh FILES -.Bl -tag -width /etc/nsswitch.conf -compact -.It Pa /etc/networks -.It Pa /etc/nsswitch.conf -.It Pa /etc/resolv.conf -.El -.Sh DIAGNOSTICS -Null pointer -(0) returned on -.Dv EOF -or error. -.Sh SEE ALSO -.Xr networks 5 -.Pp -.%T RFC 1101 -.Sh HISTORY -The -.Fn getnetent , -.Fn getnetbyaddr , -.Fn getnetbyname , -.Fn setnetent , -and -.Fn endnetent -functions appeared in -.Bx 4.2 . -.Sh BUGS -The data space used by -these functions is static; if future use requires the data, it should be -copied before any subsequent calls to these functions overwrite it. -Only Internet network -numbers are currently understood. -Expecting network numbers to fit -in no more than 32 bits is probably -naive. diff --git a/net/getprotoent.3 b/net/getprotoent.3 deleted file mode 100644 index 18b5654..0000000 --- a/net/getprotoent.3 +++ /dev/null @@ -1,149 +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. -.\" -.\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/getprotoent.3,v 1.8 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt GETPROTOENT 3 -.Os -.Sh NAME -.Nm getprotoent , -.Nm getprotobynumber , -.Nm getprotobyname , -.Nm setprotoent , -.Nm endprotoent -.Nd get protocol entry -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netdb.h -.Ft struct protoent * -.Fn getprotoent void -.Ft struct protoent * -.Fn getprotobyname "const char *name" -.Ft struct protoent * -.Fn getprotobynumber "int proto" -.Ft void -.Fn setprotoent "int stayopen" -.Ft void -.Fn endprotoent void -.Sh DESCRIPTION -The -.Fn getprotoent , -.Fn getprotobyname , -and -.Fn getprotobynumber -functions -each return a pointer to an object with the -following structure -containing the broken-out -fields of a line in the network protocol data base, -.Pa /etc/protocols . -.Bd -literal -offset indent -.Pp -struct protoent { - char *p_name; /* official name of protocol */ - char **p_aliases; /* alias list */ - int p_proto; /* protocol number */ -}; -.Ed -.Pp -The members of this structure are: -.Bl -tag -width p_aliases -.It Fa p_name -The official name of the protocol. -.It Fa p_aliases -A zero terminated list of alternate names for the protocol. -.It Fa p_proto -The protocol number. -.El -.Pp -The -.Fn getprotoent -function -reads the next line of the file, opening the file if necessary. -.Pp -The -.Fn setprotoent -function -opens and rewinds the file. If the -.Fa stayopen -flag is non-zero, -the net data base will not be closed after each call to -.Fn getprotobyname -or -.Fn getprotobynumber . -.Pp -The -.Fn endprotoent -function -closes the file. -.Pp -The -.Fn getprotobyname -function -and -.Fn getprotobynumber -sequentially search from the beginning -of the file until a matching -protocol name or -protocol number is found, -or until -.Dv EOF -is encountered. -.Sh RETURN VALUES -Null pointer -(0) returned on -.Dv EOF -or error. -.Sh FILES -.Bl -tag -width /etc/protocols -compact -.It Pa /etc/protocols -.El -.Sh SEE ALSO -.Xr protocols 5 -.Sh HISTORY -The -.Fn getprotoent , -.Fn getprotobynumber , -.Fn getprotobyname , -.Fn setprotoent , -and -.Fn endprotoent -functions appeared in -.Bx 4.2 . -.Sh BUGS -These functions use a static data space; -if the data is needed for future use, it should be -copied before any subsequent calls overwrite it. -Only the Internet -protocols are currently understood. diff --git a/net/getservent.3 b/net/getservent.3 deleted file mode 100644 index 3d398bd..0000000 --- a/net/getservent.3 +++ /dev/null @@ -1,158 +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. -.\" -.\" From: @(#)getservent.3 8.3 (Berkeley) 1/12/94 -.\" $FreeBSD: src/lib/libc/net/getservent.3,v 1.12 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd July 9, 1995 -.Dt GETSERVENT 3 -.Os -.Sh NAME -.Nm getservent , -.Nm getservbyport , -.Nm getservbyname , -.Nm setservent , -.Nm endservent -.Nd get service entry -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In netdb.h -.Ft struct servent * -.Fn getservent -.Ft struct servent * -.Fn getservbyname "const char *name" "const char *proto" -.Ft struct servent * -.Fn getservbyport "int port" "const char *proto" -.Ft void -.Fn setservent "int stayopen" -.Ft void -.Fn endservent void -.Sh DESCRIPTION -The -.Fn getservent , -.Fn getservbyname , -and -.Fn getservbyport -functions -each return a pointer to an object with the -following structure -containing the broken-out -fields of a line in the network services data base, -.Pa /etc/services . -.Bd -literal -offset indent -struct servent { - char *s_name; /* official name of service */ - char **s_aliases; /* alias list */ - int s_port; /* port service resides at */ - char *s_proto; /* protocol to use */ -}; -.Ed -.Pp -The members of this structure are: -.Bl -tag -width s_aliases -.It Fa s_name -The official name of the service. -.It Fa s_aliases -A zero terminated list of alternate names for the service. -.It Fa s_port -The port number at which the service resides. -Port numbers are returned in network byte order. -.It Fa s_proto -The name of the protocol to use when contacting the -service. -.El -.Pp -The -.Fn getservent -function -reads the next line of the file, opening the file if necessary. -.Pp -The -.Fn setservent -function -opens and rewinds the file. If the -.Fa stayopen -flag is non-zero, -the net data base will not be closed after each call to -.Fn getservbyname -or -.Fn getservbyport . -.Pp -The -.Fn endservent -function -closes the file. -.Pp -The -.Fn getservbyname -and -.Fn getservbyport -functions -sequentially search from the beginning -of the file until a matching -protocol name or -port number (which must be specified in -network byte order) is found, -or until -.Dv EOF -is encountered. -If a protocol name is also supplied (non- -.Dv NULL ) , -searches must also match the protocol. -.Sh FILES -.Bl -tag -width /etc/services -compact -.It Pa /etc/services -.El -.Sh DIAGNOSTICS -Null pointer -(0) returned on -.Dv EOF -or error. -.Sh SEE ALSO -.Xr getprotoent 3 , -.Xr services 5 -.Sh HISTORY -The -.Fn getservent , -.Fn getservbyport , -.Fn getservbyname , -.Fn setservent , -and -.Fn endservent -functions appeared in -.Bx 4.2 . -.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. -Expecting port numbers to fit in a 32 bit -quantity is probably naive. diff --git a/net/if_indextoname.3 b/net/if_indextoname.3 deleted file mode 100644 index 4b5bff5..0000000 --- a/net/if_indextoname.3 +++ /dev/null @@ -1,142 +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. -.\" -.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/if_indextoname.3,v 1.7 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd May 21, 1998 -.Dt IF_NAMETOINDEX 3 -.Os -.Sh NAME -.Nm if_nametoindex , -.Nm if_indextoname , -.Nm if_nameindex , -.Nm if_freenameindex -.Nd convert interface index to name, and vice versa -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In sys/socket.h -.In net/if.h -.Ft "unsigned int" -.Fn if_nametoindex "const char *ifname" -.Ft "char *" -.Fn if_indextoname "unsigned int ifindex" "char *ifname" -.Ft "struct if_nameindex *" -.Fn if_nameindex "void" -.Ft "void" -.Fn if_freenameindex "struct if_nameindex *ptr" -.Sh DESCRIPTION -The functions map interface index to readable interface name -(such as -.Dq Li lo0 ) , -and vice versa. -.Pp -.Fn if_nametoindex -converts readable interface name to interface index -.Pp positive integer value . -If the specified interface does not exist, 0 will be returned. -.Pp -.Fn if_indextoname -converts interface index to readable interface name. -The -.Fa ifname -argument must point to a buffer of at least -.Dv IF_NAMESIZE -bytes into which the interface name corresponding to the specified index is -returned. -.Dv ( IF_NAMESIZE -is also defined in -.Aq Pa net/if.h -and its value includes a terminating null byte at the end of the -interface name.) -This pointer is also the return value of the function. -If there is no interface corresponding to the specified index, -.Dv NULL -is returned. -.Pp -.Fn if_nameindex -returns an array of -.Fa if_nameindex -structures. -.Fa if_nametoindex -is also defined in -.Aq Pa net/if.h , -and is as follows: -.Bd -literal -offset -struct if_nameindex { - unsigned int if_index; /* 1, 2, ... */ - char *if_name; /* null terminated name: "le0", ... */ -}; -.Ed -.Pp -The end of the array of structures is indicated by a structure with -an -.Fa if_index -of 0 and an -.Fa if_name -of -.Dv NULL . -The function returns a -.Dv NULL -pointer upon an error. -The memory used for this array of structures along with the interface -names pointed to by the -.Fa if_name -members is obtained dynamically. -This memory is freed by the -.Fn if_freenameindex -function. -.Pp -.Fn if_freenameindex -takes a pointer that was returned by -.Fn if_nameindex -as argument -.Pq Fa ptr , -and it reclaims the region allocated. -.Sh DIAGNOSTICS -.Fn if_nametoindex -returns 0 on error, positive integer on success. -.Fn if_indextoname -and -.Fn if_nameindex -return -.Dv NULL -on errors. -.Sh SEE ALSO -R. Gilligan, S. Thomson, J. Bound, and W. Stevens, -``Basic Socket Interface Extensions for IPv6,'' RFC2553, March 1999. -.Sh HISTORY -The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit. -.Sh STANDARDS -These functions are defined in ``Basic Socket Interface Extensions for IPv6'' -(RFC2533). diff --git a/net/inet6_option_space.3 b/net/inet6_option_space.3 deleted file mode 100644 index 4ef8047..0000000 --- a/net/inet6_option_space.3 +++ /dev/null @@ -1,445 +0,0 @@ -.\" Copyright (c) 1983, 1987, 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. -.\" -.\" $Id: inet6_option_space.3,v 1.1 2001/12/18 01:21:21 bbraun Exp $ -.\" $FreeBSD: src/lib/libc/net/inet6_option_space.3,v 1.8 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd December 10, 1999 -.Dt INET6_OPTION_SPACE 3 -.Os -.\" -.Sh NAME -.Nm inet6_option_space , -.Nm inet6_option_init , -.Nm inet6_option_append , -.Nm inet6_option_alloc , -.Nm inet6_option_next , -.Nm inet6_option_find -.Nd IPv6 Hop-by-Hop and Destination Options manipulation -.\" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In netinet/in.h -.Ft "int" -.Fn inet6_option_space "int nbytes" -.Ft "int" -.Fn inet6_option_init "void *bp" "struct cmsghdr **cmsgp" "int type" -.Ft "int" -.Fn inet6_option_append "struct cmsghdr *cmsg" "const u_int8_t *typep" "int multx" "int plusy" -.Ft "u_int8_t *" -.Fn inet6_option_alloc "struct cmsghdr *cmsg" "int datalen" "int multx" "int plusy" -.Ft "int" -.Fn inet6_option_next "const struct cmsghdr *cmsg" "u_int8_t **tptrp" -.Ft "int" -.Fn inet6_option_find "const struct cmsghdr *cmsg" "u_int8_t **tptrp" "int type" -.\" -.Sh DESCRIPTION -.\" -Building and parsing the Hop-by-Hop and Destination options is -complicated due to alignment constranints, padding and -ancillary data manipulation. -RFC2292 defines a set of functions to help the application. -The function prototypes for -these functions are all in the -.Aq Li netinet/in.h -header. -.\" -.Ss inet6_option_space -.Fn inet6_option_space -returns the number of bytes required to hold an option when it is stored as -ancillary data, including the -.Li cmsghdr -structure at the beginning, -and any padding at the end -(to make its size a multiple of 8 bytes). -The argument is the size of the structure defining the option, -which must include any pad bytes at the beginning -(the value -.Li y -in the alignment term -.Dq Li "xn + y" ) , -the type byte, the length byte, and the option data. -.Pp -Note: If multiple options are stored in a single ancillary data -object, which is the recommended technique, this function -overestimates the amount of space required by the size of -.Li N-1 -.Li cmsghdr -structures, -where -.Li N -is the number of options to be stored in the object. -This is of little consequence, since it is assumed that most -Hop-by-Hop option headers and Destination option headers carry only -one option -(appendix B of [RFC-2460]). -.\" -.Ss inet6_option_init -.Fn inet6_option_init -is called once per ancillary data object that will -contain either Hop-by-Hop or Destination options. -It returns -.Li 0 -on success or -.Li -1 -on an error. -.Pp -.Fa bp -is a pointer to previously allocated space that will contain the -ancillary data object. -It must be large enough to contain all the -individual options to be added by later calls to -.Fn inet6_option_append -and -.Fn inet6_option_alloc . -.Pp -.Fa cmsgp -is a pointer to a pointer to a -.Li cmsghdr -structure. -.Fa *cmsgp -is initialized by this function to point to the -.Li cmsghdr -structure constructed by this function in the buffer pointed to by -.Fa bp . -.Pp -.Fa type -is either -.Dv IPV6_HOPOPTS -or -.Dv IPV6_DSTOPTS . -This -.Fa type -is stored in the -.Li cmsg_type -member of the -.Li cmsghdr -structure pointed to by -.Fa *cmsgp . -.\" -.Ss inet6_option_append -This function appends a Hop-by-Hop option or a Destination option -into an ancillary data object that has been initialized by -.Fn inet6_option_init . -This function returns -.Li 0 -if it succeeds or -.Li -1 -on an error. -.Pp -.Fa cmsg -is a pointer to the -.Li cmsghdr -structure that must have been -initialized by -.Fn inet6_option_init . -.Pp -.Fa typep -is a pointer to the 8-bit option type. -It is assumed that this -field is immediately followed by the 8-bit option data length field, -which is then followed immediately by the option data. -The caller -initializes these three fields -(the type-length-value, or TLV) -before calling this function. -.Pp -The option type must have a value from -.Li 2 -to -.Li 255 , -inclusive. -.Li ( 0 -and -.Li 1 -are reserved for the -.Li Pad1 -and -.Li PadN -options, respectively.) -.Pp -The option data length must have a value between -.Li 0 -and -.Li 255 , -inclusive, and is the length of the option data that follows. -.Pp -.Fa multx -is the value -.Li x -in the alignment term -.Dq Li xn + y . -It must have a value of -.Li 1 , -.Li 2 , -.Li 4 , -or -.Li 8 . -.Pp -.Fa plusy -is the value -.Li y -in the alignment term -.Dq Li xn + y . -It must have a value between -.Li 0 -and -.Li 7 , -inclusive. -.\" -.Ss inet6_option_alloc -This function appends a Hop-by-Hop option or a Destination option -into an ancillary data object that has been initialized by -.Fn inet6_option_init . -This function returns a pointer to the 8-bit -option type field that starts the option on success, or -.Dv NULL -on an error. -.Pp -The difference between this function and -.Fn inet6_option_append -is that the latter copies the contents of a previously built option into -the ancillary data object while the current function returns a -pointer to the space in the data object where the option's TLV must -then be built by the caller. -.Pp -.Fa cmsg -is a pointer to the -.Li cmsghdr -structure that must have been -initialized by -.Fn inet6_option_init . -.Pp -.Fa datalen -is the value of the option data length byte for this option. -This value is required as an argument to allow the function to -determine if padding must be appended at the end of the option. -(The -.Fn inet6_option_append -function does not need a data length argument -since the option data length must already be stored by the caller.) -.Pp -.Fa multx -is the value -.Li x -in the alignment term -.Dq Li xn + y . -It must have a value of -.Li 1 , -.Li 2 , -.Li 4 , -or -.Li 8 . -.Pp -.Fa plusy -is the value -.Li y -in the alignment term -.Dq Li xn + y . -It must have a value between -.Li 0 -and -.Li 7 , -inclusive. -.\" -.Ss inet6_option_next -This function processes the next Hop-by-Hop option or Destination -option in an ancillary data object. -If another option remains to be -processed, the return value of the function is -.Li 0 -and -.Fa *tptrp -points to -the 8-bit option type field -(which is followed by the 8-bit option -data length, followed by the option data). -If no more options remain -to be processed, the return value is -.Li -1 -and -.Fa *tptrp -is -.Dv NULL . -If an error occurs, the return value is -.Li -1 -and -.Fa *tptrp -is not -.Dv NULL . -.Pp -.Fa cmsg -is a pointer to -.Li cmsghdr -structure of which -.Li cmsg_level -equals -.Dv IPPROTO_IPV6 -and -.Li cmsg_type -equals either -.Dv IPV6_HOPOPTS -or -.Dv IPV6_DSTOPTS . -.Pp -.Fa tptrp -is a pointer to a pointer to an 8-bit byte and -.Fa *tptrp -is used -by the function to remember its place in the ancillary data object -each time the function is called. -The first time this function is -called for a given ancillary data object, -.Fa *tptrp -must be set to -.Dv NULL . -.Pp -Each time this function returns success, -.Fa *tptrp -points to the 8-bit -option type field for the next option to be processed. -.\" -.Ss inet6_option_find -This function is similar to the previously described -.Fn inet6_option_next -function, except this function lets the caller -specify the option type to be searched for, instead of always -returning the next option in the ancillary data object. -.Fa cmsg -is a -pointer to -.Li cmsghdr -structure of which -.Li cmsg_level -equals -.Dv IPPROTO_IPV6 -and -.Li cmsg_type -equals either -.Dv IPV6_HOPOPTS -or -.Dv IPV6_DSTOPTS . -.Pp -.Fa tptrp -is a pointer to a pointer to an 8-bit byte and -.Fa *tptrp -is used -by the function to remember its place in the ancillary data object -each time the function is called. -The first time this function is -called for a given ancillary data object, -.Fa *tptrp -must be set to -.Dv NULL . -.Pa -This function starts searching for an option of the specified type -beginning after the value of -.Fa *tptrp . -If an option of the specified -type is located, this function returns -.Li 0 -and -.Fa *tptrp -points to the 8- -bit option type field for the option of the specified type. -If an -option of the specified type is not located, the return value is -.Li -1 -and -.Fa *tptrp -is -.Dv NULL . -If an error occurs, the return value is -.Li -1 -and -.Fa *tptrp -is not -.Dv NULL . -.\" -.Sh DIAGNOSTICS -.Fn inet6_option_init -and -.Fn inet6_option_append -return -.Li 0 -on success or -.Li -1 -on an error. -.Pp -.Fn inet6_option_alloc -returns -.Dv NULL -on an error. -.Pp -On errors, -.Fn inet6_option_next -and -.Fn inet6_option_find -return -.Li -1 -setting -.Fa *tptrp -to non -.Dv NULL -value. -.\" -.Sh EXAMPLES -RFC2292 gives comprehensive examples in chapter 6. -.\" -.Sh SEE ALSO -.Rs -.%A W. Stevens -.%A M. Thomas -.%T "Advanced Sockets API for IPv6" -.%N RFC2292 -.%D February 1998 -.Re -.Rs -.%A S. Deering -.%A R. Hinden -.%T "Internet Protocol, Version 6 (IPv6) Specification" -.%N RFC2460 -.%D December 1998 -.Re -.\" -.Sh HISTORY -The implementation first appeared in KAME advanced networking kit. -.\" -.Sh STANDARDS -The functions -are documented in -.Dq Advanced Sockets API for IPv6 -(RFC2292). -.\" -.Sh BUGS -The text was shamelessly copied from RFC2292. diff --git a/net/inet6_rthdr_space.3 b/net/inet6_rthdr_space.3 deleted file mode 100644 index 42a4662..0000000 --- a/net/inet6_rthdr_space.3 +++ /dev/null @@ -1,323 +0,0 @@ -.\" Copyright (c) 1983, 1987, 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. -.\" -.\" $Id: inet6_rthdr_space.3,v 1.1 2001/12/18 01:21:22 bbraun Exp $ -.\" $FreeBSD: src/lib/libc/net/inet6_rthdr_space.3,v 1.8 2001/10/01 16:08:55 ru Exp $ -.\" -.Dd December 10, 1999 -.Dt INET6_RTHDR_SPACE 3 -.Os -.\" -.Sh NAME -.Nm inet6_rthdr_space , -.Nm inet6_rthdr_init , -.Nm inet6_rthdr_add , -.Nm inet6_rthdr_lasthop , -.Nm inet6_rthdr_reverse , -.Nm inet6_rthdr_segments , -.Nm inet6_rthdr_getaddr , -.Nm inet6_rthdr_getflags -.Nd IPv6 Routing Header Options manipulation -.\" -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In netinet/in.h -.Ft size_t -.Fn inet6_rthdr_space "int type" "int segments" -.Ft "struct cmsghdr *" -.Fn inet6_rthdr_init "void *bp" "int type" -.Ft int -.Fn inet6_rthdr_add "struct cmsghdr *cmsg" "const struct in6_addr *addr" "unsigned int flags" -.Ft int -.Fn inet6_rthdr_lasthop "struct cmsghdr *cmsg" "unsigned int flags" -.Ft int -.Fn inet6_rthdr_reverse "const struct cmsghdr *in" "struct cmsghdr *out" -.Ft int -.Fn inet6_rthdr_segments "const struct cmsghdr *cmsg" -.Ft "struct in6_addr *" -.Fn inet6_rthdr_getaddr "struct cmsghdr *cmsg" "int index" -.Ft int -.Fn inet6_rthdr_getflags "const struct cmsghdr *cmsg" "int index" -.\" -.Sh DESCRIPTION -RFC2292 IPv6 advanced API defines eight -functions that the application calls to build and examine a Routing -header. Four functions build a Routing header: -.Bl -hang -.It Fn inet6_rthdr_space -return #bytes required for ancillary data -.It Fn inet6_rthdr_init -initialize ancillary data for Routing header -.It Fn inet6_rthdr_add -add IPv6 address & flags to Routing header -.It Fn inet6_rthdr_lasthop -specify the flags for the final hop -.El -.Pp -Four functions deal with a returned Routing header: -.Bl -hang -.It Fn inet6_rthdr_reverse -reverse a Routing header -.It Fn inet6_rthdr_segments -return #segments in a Routing header -.It Fn inet6_rthdr_getaddr -fetch one address from a Routing header -.It Fn inet6_rthdr_getflags -fetch one flag from a Routing header -.El -.Pp -The function prototypes for these functions are all in the -.Aq Li netinet/in.h -header. -.\" -.Ss inet6_rthdr_space -This function returns the number of bytes required to hold a Routing -header of the specified -.Fa type -containing the specified number of -.Fa segments -(addresses). -For an IPv6 Type 0 Routing header, the number -of segments must be between 1 and 23, inclusive. The return value -includes the size of the cmsghdr structure that precedes the Routing -header, and any required padding. -.Pp -If the return value is 0, then either the type of the Routing header -is not supported by this implementation or the number of segments is -invalid for this type of Routing header. -.Pp -Note: This function returns the size but does not allocate the space -required for the ancillary data. -This allows an application to -allocate a larger buffer, if other ancillary data objects are -desired, since all the ancillary data objects must be specified to -.Xr sendmsg 2 -as a single -.Li msg_control -buffer. -.\" -.Ss inet6_rthdr_init -This function initializes the buffer pointed to by -.Fa bp -to contain a -.Li cmsghdr -structure followed by a Routing header of the specified -.Fa type . -The -.Li cmsg_len -member of the -.Li cmsghdr -structure is initialized to the -size of the structure plus the amount of space required by the -Routing header. -The -.Li cmsg_level -and -.Li cmsg_type -members are also initialized as required. -.Pp -The caller must allocate the buffer and its size can be determined by -calling -.Fn inet6_rthdr_space . -.Pp -Upon success the return value is the pointer to the -.Li cmsghdr -structure, and this is then used as the first argument to the next -two functions. -Upon an error the return value is -.Dv NULL . -.\" -.Ss inet6_rthdr_add -This function adds the address pointed to by -.Fa addr -to the end of the -Routing header being constructed and sets the type of this hop to the -value of -.Fa flags . -For an IPv6 Type 0 Routing header, -.Fa flags -must be -either -.Dv IPV6_RTHDR_LOOSE -or -.Dv IPV6_RTHDR_STRICT . -.Pp -If successful, the -.Li cmsg_len -member of the -.Li cmsghdr -structure is -updated to account for the new address in the Routing header and the -return value of the function is 0. -Upon an error the return value of -the function is -1. -.\" -.Ss inet6_rthdr_lasthop -This function specifies the Strict/Loose flag for the final hop of a -Routing header. -For an IPv6 Type 0 Routing header, -.Fa flags -must be either -.Dv IPV6_RTHDR_LOOSE -or -.Dv IPV6_RTHDR_STRICT . -.Pp -The return value of the function is 0 upon success, or -1 upon an error. -.Pp -Notice that a Routing header specifying -.Li N -intermediate nodes requires -.Li N+1 -Strict/Loose flags. -This requires -.Li N -calls to -.Fn inet6_rthdr_add -followed by one call to -.Fn inet6_rthdr_lasthop . -.\" -.Ss inet6_rthdr_reverse -This function is not yet implemented. -When implemented, this should behave as follows. -.Pp -This function takes a Routing header that was received as ancillary -data -(pointed to by the first argument, -.Fa in ) -and writes a new Routing -header that sends datagrams along the reverse of that route. -Both -arguments are allowed to point to the same buffer -(that is, the reversal can occur in place). -.Pp -The return value of the function is 0 on success, or -1 upon an -error. -.\" -.Ss inet6_rthdr_segments -This function returns the number of segments -(addresses) -contained in -the Routing header described by -.Fa cmsg . -On success the return value is -between 1 and 23, inclusive. -The return value of the function is -1 upon an error. -.\" -.Ss inet6_rthdr_getaddr -This function returns a pointer to the IPv6 address specified by -.Fa index -(which must have a value between 1 and the value returned by -.Fn inet6_rthdr_segments ) -in the Routing header described by -.Fa cmsg . -An -application should first call -.Fn inet6_rthdr_segments -to obtain the number of segments in the Routing header. -.Pp -Upon an error the return value of the function is -.Dv NULL . -.\" -.Ss inet6_rthdr_getflags -This function returns the flags value specified by -.Fa index -(which must -have a value between 0 and the value returned by -.Fn inet6_rthdr_segments ) -in the Routing header described by -.Fa cmsg . -For an IPv6 Type 0 Routing header the return value will be either -.Dv IPV6_RTHDR_LOOSE -or -.Dv IPV6_RTHDR_STRICT . -.Pp -Upon an error the return value of the function is -1. -.Pp -Note: Addresses are indexed starting at 1, and flags starting at 0, -to maintain consistency with the terminology and figures in RFC2460. -.\" -.Sh DIAGNOSTICS -.Fn inet6_rthdr_space -returns 0 on errors. -.Pp -.Fn inet6_rthdr_add , -.Fn inet6_rthdr_lasthop -and -.Fn inet6_rthdr_reverse -return 0 on success, and returns -1 on error. -.Pp -.Fn inet6_rthdr_init -and -.Fn inet6_rthdr_getaddr -return -.Dv NULL -on error. -.Pp -.Fn inet6_rthdr_segments -and -.Fn inet6_rthdr_getflags -return -1 on error. -.\" -.Sh EXAMPLES -RFC2292 gives comprehensive examples in chapter 8. -.\" -.Sh SEE ALSO -.Rs -.%A W. Stevens -.%A M. Thomas -.%T "Advanced Sockets API for IPv6" -.%N RFC2292 -.%D February 1998 -.Re -.Rs -.%A S. Deering -.%A R. Hinden -.%T "Internet Protocol, Version 6 (IPv6) Specification" -.%N RFC2460 -.%D December 1998 -.Re -.\" -.Sh HISTORY -The implementation first appeared in KAME advanced networking kit. -.\" -.Sh STANDARDS -The functions -are documented in -.Dq Advanced Sockets API for IPv6 -(RFC2292). -.\" -.Sh BUGS -The text was shamelessly copied from RFC2292. -.Pp -.Fn inet6_rthdr_reverse -is not implemented yet. diff --git a/net/ns.3 b/net/ns.3 deleted file mode 100644 index be8d155..0000000 --- a/net/ns.3 +++ /dev/null @@ -1,133 +0,0 @@ -.\" 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. -.\" -.\" @(#)ns.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/ns.3,v 1.10 2001/10/01 16:08:56 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt NS 3 -.Os -.Sh NAME -.Nm ns_addr , -.Nm ns_ntoa -.Nd Xerox -.Tn NS Ns (tm) -address conversion routines -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/types.h -.In netns/ns.h -.Ft struct ns_addr -.Fn ns_addr "char *cp" -.Ft char * -.Fn ns_ntoa "struct ns_addr ns" -.Sh DESCRIPTION -The routine -.Fn ns_addr -interprets character strings representing -.Tn XNS -addresses, returning binary information suitable -for use in system calls. -The routine -.Fn ns_ntoa -takes -.Tn XNS -addresses and returns -.Tn ASCII -strings representing the address in a -notation in common use in the Xerox Development Environment: -.Bd -ragged -offset indent -.. -.Ed -.Pp -Trailing zero fields are suppressed, and each number is printed in hexadecimal, -in a format suitable for input to -.Fn ns_addr . -Any fields lacking super-decimal digits will have a -trailing -.Ql H -appended. -.Pp -Unfortunately, no universal standard exists for representing -.Tn XNS -addresses. -An effort has been made to insure that -.Fn ns_addr -be compatible with most formats in common use. -It will first separate an address into 1 to 3 fields using a single delimiter -chosen from -period -.Ql \&. , -colon -.Ql \&: -or pound-sign -.Ql \&# . -Each field is then examined for byte separators (colon or period). -If there are byte separators, each subfield separated is taken to be -a small hexadecimal number, and the entirety is taken as a network-byte-ordered -quantity to be zero extended in the high-network-order bytes. -Next, the field is inspected for hyphens, in which case -the field is assumed to be a number in decimal notation -with hyphens separating the millenia. -Next, the field is assumed to be a number: -It is interpreted -as hexadecimal if there is a leading -.Ql 0x -(as in C), -a trailing -.Ql H -(as in Mesa), or there are any super-decimal digits present. -It is interpreted as octal is there is a leading -.Ql 0 -and there are no super-octal digits. -Otherwise, it is converted as a decimal number. -.Sh RETURN VALUES -None. (See -.Sx BUGS . ) -.Sh SEE ALSO -.Xr hosts 5 , -.Xr networks 5 -.Sh HISTORY -The -.Fn ns_addr -and -.Fn ns_toa -functions appeared in -.Bx 4.3 . -.Sh BUGS -The string returned by -.Fn ns_ntoa -resides in a static memory area. -The function -.Fn ns_addr -should diagnose improperly formed input, and there should be an unambiguous -way to recognize this. diff --git a/net/nsap_addr.c b/net/nsap_addr.c deleted file mode 100644 index f04336c..0000000 --- a/net/nsap_addr.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id: nsap_addr.c,v 1.4 2002/05/17 21:00:31 bbraun Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(isxdigit) /* XXX - could be a function */ -static int -isxdigit(c) - register int c; -{ - return ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F')); -} -#endif - -static char -xtob(c) - register 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; -{ - register u_char c, nib; - u_int len = 0; - - while ((c = *ascii++) != '\0' && len < maxlen) { - if (c == '.' || c == '+' || c == '/') - continue; - if (!isascii(c)) - return (0); - if (islower(c)) - c = toupper(c); - if (isxdigit(c)) { - nib = xtob(c); - if (c = *ascii++) { - c = toupper(c); - if (isxdigit(c)) { - *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; - register const u_char *binary; - register char *ascii; -{ - register 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); -} diff --git a/net/nsdispatch.3 b/net/nsdispatch.3 deleted file mode 100644 index 708f97c..0000000 --- a/net/nsdispatch.3 +++ /dev/null @@ -1,231 +0,0 @@ -.\" $NetBSD: nsdispatch.3,v 1.8 1999/03/22 19:44:53 garbled Exp $ -.\" $FreeBSD: src/lib/libc/net/nsdispatch.3,v 1.5 2001/10/01 16:08:56 ru Exp $ -.\" -.\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to The NetBSD Foundation -.\" by Luke Mewburn. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the 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 January 19, 1999 -.Dt NSDISPATCH 3 -.Os -.Sh NAME -.Nm nsdispatch -.Nd name-service switch dispatcher routine -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In nsswitch.h -.Ft int -.Fo nsdispatch -.Fa "void *retval" -.Fa "const ns_dtab dtab[]" -.Fa "const char *database" -.Fa "const char *method" -.Fa "const ns_src defaults[]" -.Fa "..." -.Fc -.Sh DESCRIPTION -The -.Fn nsdispatch -function invokes the callback functions specified in -.Va dtab -in the order given in -.Pa /etc/nsswitch.conf -for the database -.Va database -until a successful entry is found. -.Pp -.Va retval -is passed to each callback function to modify as necessary -(to pass back to the caller of -.Fn nsdispatch ) -.Pp -.Va dtab -is an array of -.Va ns_dtab -structures, which have the following format: -.Bd -literal -offset indent -typedef struct { - const char *src; - int (*cb)(void *retval, void *cb_data, va_list ap); - void *cb_data; -} ns_dtab; -.Ed -.Pp -.Bd -ragged -offset indent -For each source type that is implemented, an entry with -.Va src -set to the name of the source, -.Va cb -defined as a function which handles that source, and -.Va cb_data -is used to pass arbritrary data to the callback function. -The last entry in -.Va dtab -should contain -.Dv NULL -values for -.Va src , -.Va cb , -and -.Va cb_data . -.Ed -.Pp -.Va method -is usually the name of the function calling -.Fn nsdispatch . -When dynamic loading is supported, a symbol constructed from -.Va database , -the current source, and -.Va method -will be used as the name to invoke the dynamically loaded function. -.Pp -.Va defaults -contains a list of default sources to try in the case of -a missing or corrupt -.Xr nsswitch.conf 5 , -or if there isn't a relevant entry for -.Va database . -It is an array of -.Va ns_src -structures, which have the following format: -.Bd -literal -offset indent -typedef struct { - const char *src; - u_int32_t flags; -} ns_src; -.Ed -.Pp -.Bd -ragged -offset indent -For each default source type, an entry with -.Va src -set to the name of the source, and -.Va flags -set to the relevant flags -(usually -.Dv NS_SUCCESS ; -refer to -.Sx Callback return values -for more information). -The last entry in -.Va defaults -should have -.Va src -set to -.Dv NULL -and -.Va flags -set to 0. -.Pp -For convenience, a global variable defined as: -.Dl extern const ns_src __nsdefaultsrc[]; -exists which contains a single default entry for -.Sq files -for use by callers which don't require complicated default rules. -.Ed -.Pp -.Sq Va ... -are optional extra arguments, which -are passed to the appropriate callback function as a variable argument -list of the type -.Va va_list . -.Ss Valid source types -Whilst there is support for arbitrary sources, the following -#defines for commonly implementated sources are available: -.Bl -column NS_COMPAT COMPAT -offset indent -.It Sy "#define value" -.It "NSSRC_FILES ""files""" -.It "NSSRC_DNS ""dns""" -.It "NSSRC_NIS ""nis""" -.It "NSSRC_COMPAT ""compat""" -.El -.Pp -Refer to -.Xr nsswitch.conf 5 -for a complete description of what each source type is. -.Pp -.Ss Callback return values -The callback functions should return one of the following values -depending upon status of the lookup: -.Bl -column NS_NOTFOUND -offset indent -.It Sy "Return value Status code" -.It "NS_SUCCESS success" -.It "NS_NOTFOUND notfound" -.It "NS_UNAVAIL unavail" -.It "NS_TRYAGAIN tryagain" -.El -.Pp -Refer to -.Xr nsswitch.conf 5 -for a complete description of what each status code is. -.Pp -.Nm -returns the value of the callback that caused the dispatcher to finish, -or NS_NOTFOUND otherwise. -.Sh SEE ALSO -.Xr hesiod 3 , -.Xr stdarg 3 , -.Xr ypclnt 3 , -.Xr nsswitch.conf 5 -.Sh HISTORY -The -.Nm -routines first appeared in -.Fx 4.1 . -They were imported from the -.Nx -Project, -where they appeared first in -.Nx 1.4 . -.Sh AUTHORS -Luke Mewburn -.Aq lukem@netbsd.org -wrote this freely distributable name-service switch implementation, -using ideas from the -.Tn ULTRIX -.Xr svc.conf 5 -and -.Tn Solaris -.Xr nsswitch.conf 4 -manual pages. -.Sh BUGS -The -.Nm -routines are not thread safe. -This will be rectified in the future. -.Pp -Currently there is no support for dynamically loadable dispatcher callback -functions. -It is anticipated that this will be added in the future in the back-end -without requiring changes to code that invokes -.Fn nsdispatch . diff --git a/net/rcmd.3 b/net/rcmd.3 deleted file mode 100644 index 9479a23..0000000 --- a/net/rcmd.3 +++ /dev/null @@ -1,298 +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. -.\" -.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/net/rcmd.3,v 1.20 2001/10/01 16:08:56 ru Exp $ -.\" -.Dd March 3, 2000 -.Dt RCMD 3 -.Os -.Sh NAME -.Nm rcmd , -.Nm rresvport , -.Nm iruserok , -.Nm ruserok , -.Nm rcmd_af , -.Nm rresvport_af , -.Nm iruserok_sa -.Nd routines for returning a stream to a remote command -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" -.Ft int -.Fn rresvport "int *port" -.Ft int -.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser" -.Ft int -.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" -.Ft int -.Fn rcmd_af "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" "int af" -.Ft int -.Fn rresvport_af "int *port" "int af" -.Ft int -.Fn iruserok_sa "const void *addr" "int addrlen" "int superuser" "const char *ruser" "const char *luser" -.Sh DESCRIPTION -The -.Fn rcmd -function -is used by the super-user to execute a command on -a remote machine using an authentication scheme based -on reserved port numbers. -The -.Fn rresvport -function -returns a descriptor to a socket -with an address in the privileged port space. -The -.Fn ruserok -function -is used by servers -to authenticate clients requesting service with -.Fn rcmd . -All three functions are present in the same file and are used -by the -.Xr rshd 8 -server (among others). -.Pp -The -.Fn rcmd -function -looks up the host -.Fa *ahost -using -.Xr gethostbyname 3 , -returning -1 if the host does not exist. -Otherwise -.Fa *ahost -is set to the standard name of the host -and a connection is established to a server -residing at the well-known Internet port -.Fa inport . -.Pp -If the connection succeeds, -a socket in the Internet domain of type -.Dv SOCK_STREAM -is returned to the caller, and given to the remote -command as -.Em stdin -and -.Em stdout . -If -.Fa fd2p -is non-zero, then an auxiliary channel to a control -process will be set up, and a descriptor for it will be placed -in -.Fa *fd2p . -The control process will return diagnostic -output from the command (unit 2) on this channel, and will also -accept bytes on this channel as being -.Tn UNIX -signal numbers, to be -forwarded to the process group of the command. -If -.Fa fd2p -is 0, then the -.Em stderr -(unit 2 of the remote -command) will be made the same as the -.Em stdout -and no -provision is made for sending arbitrary signals to the remote process, -although you may be able to get its attention by using out-of-band data. -.Pp -The protocol is described in detail in -.Xr rshd 8 . -.Pp -The -.Fn rresvport -function is used to obtain a socket to which an address with a Privileged -Internet port is bound. -This socket is suitable for use by -.Fn rcmd -and several other functions. -Privileged Internet ports are those in the range 0 to 1023. -Only the super-user is allowed to bind an address of this sort -to a socket. -.Pp -The -.Fn iruserok -and -.Fn ruserok -functions take a remote host's IP address or name, as returned by the -.Xr gethostbyname 3 -routines, two user names and a flag indicating whether the local user's -name is that of the super-user. -Then, if the user is -.Em NOT -the super-user, it checks the -.Pa /etc/hosts.equiv -file. -If that lookup is not done, or is unsuccessful, the -.Pa .rhosts -in the local user's home directory is checked to see if the request for -service is allowed. -.Pp -If this file does not exist, is not a regular file, is owned by anyone -other than the user or the super-user, or is writable by anyone other -than the owner, the check automatically fails. -Zero is returned if the machine name is listed in the -.Dq Pa hosts.equiv -file, or the host and remote user name are found in the -.Dq Pa .rhosts -file; otherwise -.Fn iruserok -and -.Fn ruserok -return -1. -If the local domain (as obtained from -.Xr gethostname 3 ) -is the same as the remote domain, only the machine name need be specified. -.Pp -The -.Fn iruserok -function is strongly preferred for security reasons. -It requires trusting the local DNS at most, while the -.Fn ruserok -function requires trusting the entire DNS, which can be spoofed. -.Pp -The functions with an -.Dq Li _af -or -.Dq Li _sa -suffix, i.e., -.Fn rcmd_af , -.Fn rresvport_af -and -.Fn iruserok_sa , -work the same as the corresponding functions without a -suffix, except that they are capable of handling both IPv6 and IPv4 ports. -.Pp -The -.Dq Li _af -suffix means that the function has an additional -.Fa af -argument which is used to specify the address family, -(see below). -The -.Fa af -argument extension is implemented for functions -that have no binary address argument. -Instead, the -.Fa af -argument specifies which address family is desired. -.Pp -The -.Dq Li _sa -suffix means that the function has general socket address and -length arguments. -As the socket address is a protocol independent data structure, -IPv4 and IPv6 socket address can be passed as desired. -The -.Fa sa -argument extension is implemented for functions -that pass a protocol dependent binary address argument. -The argument needs to be replaced with a more general address structure -to support multiple address families in a general way. -.Pp -The functions with neither an -.Dq Li _af -suffix nor an -.Dq Li _sa -suffix work for IPv4 only, except for -.Fn ruserok -which can handle both IPv6 and IPv4. -To switch the address family, the -.Fa af -argument must be filled with -.Dv AF_INET , -or -.Dv AF_INET6 . -For -.Fn rcmd_af , -.Dv PF_UNSPEC -is also allowed. -.Sh DIAGNOSTICS -The -.Fn rcmd -function -returns a valid socket descriptor on success. -It returns -1 on error and prints a diagnostic message -on the standard error. -.Pp -The -.Fn rresvport -function -returns a valid, bound socket descriptor on success. -It returns -1 on error with the global value -.Va errno -set according to the reason for failure. -The error code -.Er EAGAIN -is overloaded to mean ``All network ports in use.'' -.Sh SEE ALSO -.Xr rlogin 1 , -.Xr rsh 1 , -.Xr intro 2 , -.Xr rexec 3 , -.Xr rexecd 8 , -.Xr rlogind 8 , -.Xr rshd 8 -.Pp -.Rs -.%A W. Stevens -.%A M. Thomas -.%T "Advanced Socket API for IPv6" -.%O RFC2292 -.Re -.Rs -.%A W. Stevens -.%A M. Thomas -.%A E. Nordmark -.%T "Advanced Socket API for IPv6" -.%O draft-ietf-ipngwg-rfc2292bis-01.txt -.Re -.Sh HISTORY -Most of these -functions appeared in -.Bx 4.2 . -.Fn rresvport_af -appeared in RFC2292, and was implemented by the WIDE project -for the Hydrangea IPv6 protocol stack kit. -.Fn rcmd_af -appeared in draft-ietf-ipngwg-rfc2292bis-01.txt, -and was implemented in the WIDE/KAME IPv6 protocol stack kit. -.Fn iruserok_sa -appeared in discussion on the IETF ipngwg mailing list, -and was implemented in -.Fx 4.0 . diff --git a/nls/FreeBSD/catclose.3 b/nls/FreeBSD/catclose.3 new file mode 100644 index 0000000..7ac7172 --- /dev/null +++ b/nls/FreeBSD/catclose.3 @@ -0,0 +1,64 @@ +.\" Copyright (c) 1994 Winning Strategies, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Winning Strategies, Inc. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software 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/nls/catclose.3,v 1.14 2001/10/01 16:08:56 ru Exp $ +.Dd May 29, 1994 +.Dt CATCLOSE 3 +.Os +.Sh NAME +.Nm catclose +.Nd close message catalog +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nl_types.h +.Ft int +.Fn catclose "nl_catd catd" +.Sh DESCRIPTION +The +.Fn catclose +function closes the message catalog specified by the argument +.Fa catd . +.Sh RETURN VALUES +.Rv -std catclose +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +An invalid message catalog descriptor was passed by the +.Fa catd +argument. +.El +.Sh SEE ALSO +.Xr gencat 1 , +.Xr catgets 3 , +.Xr catopen 3 +.Sh STANDARDS +The +.Fn catclose +function conforms to +.St -xpg4 . diff --git a/nls/FreeBSD/catgets.3 b/nls/FreeBSD/catgets.3 new file mode 100644 index 0000000..905e2cb --- /dev/null +++ b/nls/FreeBSD/catgets.3 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1994 Winning Strategies, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Winning Strategies, Inc. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software 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/nls/catgets.3,v 1.11 2001/10/01 16:08:56 ru Exp $ +.Dd May 29, 1994 +.Dt CATGETS 3 +.Os +.Sh NAME +.Nm catgets +.Nd retrieve string from message catalog +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nl_types.h +.Ft char * +.Fn catgets "nl_catd catd" "int set_id" "int msg_id" "const char *s" +.Sh DESCRIPTION +The +.Fn catgets +function attempts to retrieve message +.Fa msg_id +of set +.Fa set_id +from the message catalog referenced by the descriptor +.Fa catd . +The argument +.Fa s +points to a default message which is returned if the function +is unable to retrieve the specified message. +.Sh RETURN VALUES +If the specified message was retrieved successfully, +.Fn catgets +returns a pointer to an internal buffer containing the message string; +otherwise it returns +.Fa s . +.Sh SEE ALSO +.Xr gencat 1 , +.Xr catclose 3 , +.Xr catopen 3 +.Sh STANDARDS +The +.Fn catgets +function conforms to +.St -xpg4 . diff --git a/nls/FreeBSD/catopen.3 b/nls/FreeBSD/catopen.3 new file mode 100644 index 0000000..ad75519 --- /dev/null +++ b/nls/FreeBSD/catopen.3 @@ -0,0 +1,157 @@ +.\" Copyright (c) 1994 Winning Strategies, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Winning Strategies, Inc. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software 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/nls/catopen.3,v 1.16 2001/10/01 16:08:56 ru Exp $ +.Dd May 29, 1994 +.Dt CATOPEN 3 +.Os +.Sh NAME +.Nm catopen +.Nd open message catalog +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nl_types.h +.Ft nl_catd +.Fn catopen "const char *name" "int oflag" +.Sh DESCRIPTION +The +.Fn catopen +function opens the message catalog specified by +.Fa name +and returns a message catalog descriptor. +If +.Fa name +contains a +.Sq / +then +.Fa name +specifies the full pathname for the message catalog, otherwise the value +of the environment variable +.Ev NLSPATH +is used with +the following substitutions: +.Bl -tag -width XXX +.It \&%N +The value of the +.Fa name +argument. +.It \&%L +The value of the +.Ev LANG +environment variable or the +.Dv LC_MESSAGES +category (see below). +.It \&%l +The language element from the +.Ev LANG +environment variable or from the +.Dv LC_MESSAGES +category. +.It \&%t +The territory element from the +.Ev LANG +environment variable or from the +.Dv LC_MESSAGES +category. +.It \&%c +The codeset element from the +.Ev LANG +environment variable or from the +.Dv LC_MESSAGES +category. +.It \&%% +A single % character. +.El +.Pp +An empty string is substituted for undefined values. +.Pp +Path names templates defined in +.Ev NLSPATH +are separated by colons +.No ( Sq \&: ) . +A leading or two adjacent colons +is equivalent to specifying %N. +.Pp +If the +.Fa oflag +argument is set to the +.Dv NL_CAT_LOCALE +constant, +.Dv LC_MESSAGES +locale category used to open the message catalog; using +.Dv NL_CAT_LOCALE +conforms to the +.St -xpg4 +standard. +You can specify 0 for compatibility with +.St -xpg3 ; +when +.Fa oflag +is set to 0, the +.Ev LANG +environment variable +determines the message catalog locale. +.Pp +A message catalog descriptor +remains valid in a process until that process closes it, or +until a successful call to one of the +.Xr exec 3 +function. +.Sh RETURN VALUES +Upon successful completion, +.Fn catopen +returns a message catalog descriptor. +Otherwise, (nl_catd) -1 is returned and +.Va errno +is set to indicate the error. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa name +does not point to a valid message catalog. +.It Bq Er ENAMETOOLONG +An entire path to the message catalog exceeded 1024 characters. +.It Bq Er ENOENT +The named message catalog does not exists, or the +.Fa name +argument points to an empty string. +.It Bq Er ENOMEM +Insufficient memory is available. +.El +.Sh SEE ALSO +.Xr gencat 1 , +.Xr catclose 3 , +.Xr catgets 3 , +.Xr setlocale 3 +.Sh STANDARDS +The +.Fn catopen +function conforms to +.St -xpg4 . diff --git a/nls/FreeBSD/msgcat.c b/nls/FreeBSD/msgcat.c new file mode 100644 index 0000000..fd9e820 --- /dev/null +++ b/nls/FreeBSD/msgcat.c @@ -0,0 +1,503 @@ +/*********************************************************** +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.45 2002/10/27 17:44:33 wollman 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 "un-namespace.h" + +#include "msgcat.h" +#include "../locale/setlocale.h" /* for ENCODING_LEN */ + +#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 = setlocale(LC_MESSAGES, 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 +#ifndef __NETBSD_SYSCALLS + || issetugid() +#endif + ) + 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 < PARENT->NUM) { \ + cur = ID - 1; \ + hi = ID; \ + } else { \ + hi = PARENT->NUM; \ + cur = (hi - lo) / 2; \ + } \ + while (TRUE) { \ + CHILD = PARENT->SET + cur; \ + if (CHILD->ID == ID) \ + break; \ + if (CHILD->ID < ID) { \ + lo = cur + 1; \ + if (hi > cur + (ID - CHILD->ID) + 1) \ + hi = cur + (ID - 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(cat, setId) + MCCatT *cat; + int setId; +{ + MCSetT *set; + long lo, hi, cur, dir; + + if (cat == NULL || setId <= 0) + return (NULL); + LOOKUP(cat, set, setId, numSets, sets); + if (set->invalid && loadSet(cat, set) <= 0) + return (NULL); + return (set); +} + +static MCMsgT * +MCGetMsg(set, msgId) + MCSetT *set; + int msgId; +{ + MCMsgT *msg; + long lo, hi, cur, dir; + + if (set == NULL || set->invalid || msgId <= 0) + return (NULL); + LOOKUP(set, msg, msgId, 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; + long 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 (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); + NLRETERR(EFTYPE); + } + if (header.numSets <= 0) { + (void)fclose(cat->fp); + free(cat); + (void)fprintf(stderr, "%s: %s has %ld sets!\n", + _errowner, catpath, header.numSets); + NLRETERR(EFTYPE); + } + + cat->numSets = header.numSets; + if ((cat->sets = (MCSetT *)malloc(sizeof(MCSetT) * header.numSets)) == + NULL) + NOSPACE(); + + nextSet = 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 = 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 = 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, set->data.off, SEEK_SET) == -1) + return (0); + if ((set->data.str = malloc(set->dataLen)) == NULL) + return (-1); + if (fread(set->data.str, set->dataLen, 1, cat->fp) != 1) { + saverr = errno; + free(set->data.str); + errno = saverr; + return (0); + } + + /* Get the messages */ + if (fseeko(cat->fp, 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)) == + NULL) { + saverr = errno; + free(set->data.str); + errno = saverr; + return (-1); + } + + for (i = 0; i < 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 + msg->msg.off); + } + set->invalid = FALSE; + return (1); +} diff --git a/nls/FreeBSD/msgcat.c.patch b/nls/FreeBSD/msgcat.c.patch new file mode 100644 index 0000000..e81ed92 --- /dev/null +++ b/nls/FreeBSD/msgcat.c.patch @@ -0,0 +1,11 @@ +--- msgcat.c.orig Sun Oct 27 09:44:33 2002 ++++ msgcat.c Sat May 3 14:19:40 2003 +@@ -54,7 +54,7 @@ + #include "un-namespace.h" + + #include "msgcat.h" +-#include "../locale/setlocale.h" /* for ENCODING_LEN */ ++#include "setlocale.h" /* for ENCODING_LEN */ + + #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" + diff --git a/nls/FreeBSD/msgcat.h b/nls/FreeBSD/msgcat.h new file mode 100644 index 0000000..df2bf5a --- /dev/null +++ b/nls/FreeBSD/msgcat.h @@ -0,0 +1,155 @@ +/* $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) (unsigned long) ( ((unsigned short)s << (sizeof(short)*8)) \ + | (unsigned short)m ) +#define MCSetId(id) (unsigned int) ( id >> (sizeof(short) * 8) ) +#define MCMsgId(id) (unsigned int) ( (id << (sizeof(short) * 8)) \ + >> (sizeof(short) * 8) ) +#define MCMagicLen 8 +#define MCMagic "*nazgul*" +#define MCLastMsg 0 +#define MCLastSet 0 + +#define MCMajorVer 1L +#define MCMinorVer 0 + +/* + * 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; + +/* + * MCMsgT - Message structure (disk and runtime) + */ +typedef struct _MCMsgT { + long msgId; /* Id of this message */ + MCOffsetT msg; /* Relative offset on disk or pointer in memory */ + long invalid; /* Valid on disk, loaded in memory */ +} MCMsgT; + +/* + * MCSetT - Set structure (disk and runtime) + */ +typedef struct _MCSetT { + long 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 */ +} MCSetT; + +/* + * MCCatT - Runtime catalog pointer + */ +typedef struct { + long loadType; /* How to load the messages (see MSLoadType) */ + FILE *fp; /* File descriptor of catalog (if load-on-demand) */ + long numSets; /* Number of sets */ + MCSetT *sets; /* Pointer to the sets */ + off_t firstSet; /* Offset of first set on disk */ +} MCCatT; + +/* + * MCHeaderT - Disk file header + */ +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 */ + off_t firstSet; /* Offset of first set on disk */ +} MCHeaderT; + +/* Some flags */ +#define MC68KByteOrder 0x01 +#define MCn86ByteOrder 0x02 + +#endif /* !_MSGCAT_H_ */ diff --git a/nls/Makefile.inc b/nls/Makefile.inc index 66329a2..94145cf 100644 --- a/nls/Makefile.inc +++ b/nls/Makefile.inc @@ -1,10 +1,18 @@ # from $NetBSD: Makefile.inc,v 1.7 1995/02/27 13:06:20 cgd Exp $ -# $FreeBSD: src/lib/libc/nls/Makefile.inc,v 1.7 2001/03/27 17:26:48 ru Exp $ +# $FreeBSD: src/lib/libc/nls/Makefile.inc,v 1.5.2.2 2001/04/25 10:04:07 ru Exp $ -.PATH: ${.CURDIR}/../libc/nls +.PATH: ${.CURDIR}/nls -SRCS+= msgcat.c +.include "Makefile.fbsd_begin" +FBSDSRCS= msgcat.c +FBSDORIGHDRS= msgcat.h +.include "Makefile.fbsd_end" + +# Install msgcat.h for usage by gencat (in adv_cmds) +LOCALHDRS+= msgcat.h .if ${LIB} == "c" -MAN+= catclose.3 catgets.3 catopen.3 +.include "Makefile.fbsd_begin" +FBSDMAN3= catclose.3 catgets.3 catopen.3 +.include "Makefile.fbsd_end" .endif diff --git a/ppc/gen/Makefile.inc b/ppc/gen/Makefile.inc index 6344540..7223519 100644 --- a/ppc/gen/Makefile.inc +++ b/ppc/gen/Makefile.inc @@ -1,6 +1,13 @@ -SRCS += abs.s bzero.s mcount.s strcmp.c strncmp.c \ - ecvt.c remque.c strcpy.c strncpy.c \ - bcmp.c ffs.s insque.c setjmperr.c strlen.s \ - bcopy.s fp.h isinf.c strcat.c strncat.c \ - mcount.s +MDSRCS += \ + abs.s \ + bcopy.s \ + bzero.s \ + ecvt.c \ + ffs.s \ + fp.h \ + icacheinval.s \ + isinf.c \ + mcount.s \ + setjmperr.c +SUPPRESSSRCS += memcpy.c memmove.c memset.c diff --git a/ppc/gen/bcopy.s b/ppc/gen/bcopy.s index e25eb72..6630063 100644 --- a/ppc/gen/bcopy.s +++ b/ppc/gen/bcopy.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,1141 +22,24 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* ======================================= - * BCOPY, MEMCPY, and MEMMOVE for Mac OS X - * ======================================= - * - * Version of 6/17/2002, for G3, G4, and G4+. - * - * There are many paths through this code, depending on length, reverse/forward, - * processor type, and alignment. We use reverse paths only when the operands - * overlap and the destination is higher than the source. They are not quite as - * fast as the forward paths. - * - * Judicious use of DCBTs, just far enough ahead to minimize waiting, is critical in - * the inner loops for long operands. DST is less effective than DCBT, because it - * can get out of sync with the inner loop. DCBTST is usually not a win, so we - * don't use it except during initialization when we're not using the LSU. - * We don't DCBT on G3, which only handles one load miss at a time. - * - * We don't use DCBZ, because it takes an alignment exception on uncached memory - * like frame buffers. Bcopy to frame buffers must work. This hurts G3 in the - * cold-cache case, but G4 can use DCBA (which does not take alignment exceptions.) - * - * Using DCBA on G4 is a tradeoff. For the cold-cache case it can be a big win, - * since it avoids the read of destination cache lines. But for the hot-cache case - * it is always slower, because of the cycles spent needlessly zeroing data. Some - * machines store-gather and can cancel the read if all bytes of a line are stored, - * others cannot. Unless explicitly told which is better, we time loops with and - * without DCBA and use the fastest. Note that we never DCBA in reverse loops, - * since by definition they are overlapped so dest lines will be in the cache. - * - * For longer operands we use an 8-element branch table, based on the CPU type, - * to select the appropriate inner loop. The branch table is indexed as follows: - * - * bit 10000 set if a Reverse move is required - * bits 01100 set on the relative operand alignment: 0=unaligned, 1=word, - * 2=doubleword, and 3=quadword. - * - * By "relatively" n-byte aligned, we mean the source and destination are a multiple - * of n bytes apart (they need not be absolutely aligned.) - * - * The branch table for the running CPU type is pointed to by LBranchTablePtr. - * Initially, LBranchtablePtr points to G3's table, since that is the lowest - * common denominator that will run on any CPU. Later, pthread initialization - * sets up the _cpu_capabilities vector and calls _bcopy_initialize, which sets - * up the correct pointer for the running CPU. - * - * We distinguish between "short", "medium", and "long" operands: - * short (<= 32 bytes) most common case, minimum path length is important - * medium (> 32, < kLong) too short for Altivec or use of cache ops like DCBA - * long (>= kLong) long enough for cache ops and to amortize use of Altivec - * - * WARNING: kLong must be >=96, due to implicit assumptions about operand length. - */ -#define kLong 96 - -/* Register usage. Note we use R2, so this code will not run in a PEF/CFM - * environment. Note also the rather delicate way we assign multiple uses - * to the same register. Beware. - * - * r0 = "w7" or "r0" (NB: cannot use r0 for any constant such as "c16") - * r2 = "w8" or VRSave ("rv") - * r3 = not used, as memcpy and memmove return 1st parameter as a value - * r4 = source ptr ("rs") - * r5 = count of bytes to move ("rc") - * r6 = "w1", "c16", or "cm17" - * r7 = "w2", "c32", or "cm33" - * r8 = "w3", "c48", or "cm49" - * r9 = "w4", "c64", or "cm1" - * r10 = "w5", "c96", or "cm97" - * r11 = "w6", "c128", "cm129", or return address ("ra") - * r12 = destination ptr ("rd") - * f0-f8 = used for moving 8-byte aligned data - * v0 = permute vector ("vp") - * v1-v4 = qw's loaded from source ("v1", "v2", "v3", and "v4") - * v5-v7 = permuted qw's ("vx", "vy", and "vz") - */ -#define rs r4 -#define rd r12 -#define rc r5 -#define ra r11 -#define rv r2 - -#define w1 r6 -#define w2 r7 -#define w3 r8 -#define w4 r9 -#define w5 r10 -#define w6 r11 -#define w7 r0 -#define w8 r2 - -#define c16 r6 -#define cm17 r6 -#define c32 r7 -#define cm33 r7 -#define c48 r8 -#define cm49 r8 -#define c64 r9 -#define cm1 r9 -#define c96 r10 -#define cm97 r10 -#define c128 r11 -#define cm129 r11 - -#define vp v0 -#define vx v5 -#define vy v6 -#define vz v7 - -#define VRSave 256 -#include - -// The branch tables, 8 entries per CPU type. -// NB: we depend on 5 low-order 0s in the address of branch tables. - - .data - .align 5 // must be 32-byte aligned - - // G3 (the default CPU type) - -LG3: - .long LForwardWord // 000: forward, unaligned - .long LForwardFloat // 001: forward, 4-byte aligned - .long LForwardFloat // 010: forward, 8-byte aligned - .long LForwardFloat // 011: forward, 16-byte aligned - .long LReverseWord // 100: reverse, unaligned - .long LReverseFloat // 101: reverse, 4-byte aligned - .long LReverseFloat // 110: reverse, 8-byte aligned - .long LReverseFloat // 111: reverse, 16-byte aligned - - // G4s that benefit from DCBA. - -LG4UseDcba: - .long LForwardVecUnal32Dcba // 000: forward, unaligned - .long LForwardVecUnal32Dcba // 001: forward, 4-byte aligned - .long LForwardVecUnal32Dcba // 010: forward, 8-byte aligned - .long LForwardVecAlig32Dcba // 011: forward, 16-byte aligned - .long LReverseVectorUnal32 // 100: reverse, unaligned - .long LReverseVectorUnal32 // 101: reverse, 4-byte aligned - .long LReverseVectorUnal32 // 110: reverse, 8-byte aligned - .long LReverseVectorAligned32 // 111: reverse, 16-byte aligned - - // G4s that should not use DCBA. - -LG4NoDcba: - .long LForwardVecUnal32NoDcba // 000: forward, unaligned - .long LForwardVecUnal32NoDcba // 001: forward, 4-byte aligned - .long LForwardVecUnal32NoDcba // 010: forward, 8-byte aligned - .long LForwardVecAlig32NoDcba // 011: forward, 16-byte aligned - .long LReverseVectorUnal32 // 100: reverse, unaligned - .long LReverseVectorUnal32 // 101: reverse, 4-byte aligned - .long LReverseVectorUnal32 // 110: reverse, 8-byte aligned - .long LReverseVectorAligned32 // 111: reverse, 16-byte aligned - - -// Pointer to the 8-element branch table for running CPU type: - -LBranchTablePtr: - .long LG3 // default to G3 until "bcopy_initialize" called - - -// The CPU capability vector, initialized in pthread_init(). -// "_bcopy_initialize" uses this to set up LBranchTablePtr: - - .globl __cpu_capabilities -__cpu_capabilities: - .long 0 - -// Bit definitions for _cpu_capabilities: - -#define kHasAltivec 0x01 -#define k64Bit 0x02 -#define kCache32 0x04 -#define kCache64 0x08 -#define kCache128 0x10 -#define kUseDcba 0x20 -#define kNoDcba 0x40 - - -.text -.globl _bcopy -.globl _memcpy -.globl _memmove -.globl __bcopy_initialize - - -// Main entry points. +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + + // These functions have migrated to the comm page. + + .text + .globl _bcopy + .globl _memcpy + .globl _memmove .align 5 _bcopy: // void bcopy(const void *src, void *dst, size_t len) - mr r10,r3 // reverse source and dest ptrs, to be like memcpy - mr r3,r4 - mr r4,r10 + ba _COMM_PAGE_BCOPY + + .align 5 _memcpy: // void* memcpy(void *dst, void *src, size_t len) _memmove: // void* memmove(void *dst, const void *src, size_t len) - cmplwi cr7,rc,32 // length <= 32 bytes? - sub. w1,r3,rs // must move in reverse if (rd-rs)=1) - mtctr w4 // prepare loop count - beq+ 2f // source already aligned - - lwzx w2,w3,rs // get 1st aligned word (which we might partially overwrite) - add rs,rs,w3 // word-align source ptr - stw w1,0(rd) // store all (w3) bytes at once to avoid a loop - add rd,rd,w3 - mr w1,w2 // first aligned word to w1 - b 2f - - .align 4 // align inner loops -1: // loop over 16-byte chunks - lwz w1,0(rs) -2: - lwz w2,4(rs) - lwz w3,8(rs) - lwz w4,12(rs) - addi rs,rs,16 - stw w1,0(rd) - stw w2,4(rd) - stw w3,8(rd) - stw w4,12(rd) - addi rd,rd,16 - bdnz 1b - - b LShort16 - - -// Medium, doubleword aligned. We use floating point. Note that G4+ has bigger latencies -// and reduced throughput for floating pt loads and stores; future processors will probably -// have even worse lfd/stfd performance. We use it here because it is so important for G3, -// and not slower for G4+. But we only do so for doubleword aligned operands, whereas the -// G3-only long operand loops use floating pt even for word-aligned operands. -// w2 = neg(rs) -// w1 = first 4 bytes of source - -LMediumAligned: - andi. w3,w2,7 // already aligned? - sub rc,rc,w3 // adjust count by 0-7 bytes - lfdx f0,rs,w3 // pre-fetch first aligned source doubleword - srwi w4,rc,5 // get count of 32-byte chunks (might be 0 if unaligned) - mtctr w4 - beq- LForwardFloatLoop1 // already aligned - - cmpwi w4,0 // are there any 32-byte chunks to xfer? - lwz w2,4(rs) // get 2nd (unaligned) source word - add rs,rs,w3 // doubleword align source pointer - stw w1,0(rd) // store first 8 bytes of source to align... - stw w2,4(rd) // ...which could overwrite source - add rd,rd,w3 // doubleword align destination - bne+ LForwardFloatLoop1 // at least 1 chunk, so enter loop - - subi rc,rc,8 // unfortunate degenerate case: no chunks to xfer - stfd f0,0(rd) // must store f1 since source might have been overwriten - addi rs,rs,8 - addi rd,rd,8 - b LShort - - -// Medium reverse moves. This loop runs on all processors. - -LMediumReverse: - add rs,rs,rc // point to other end of operands when in reverse - add rd,rd,rc - andi. w3,rs,3 // w3 <- #bytes to word align source - lwz w1,-4(rs) // pre-fetch 1st 4 bytes of source - sub rc,rc,w3 // adjust count - srwi w4,rc,4 // get count of 16-byte chunks (>=1) - mtcrf 0x01,rc // remaining byte count (0-15) to cr7 for LShortReverse16 - mtctr w4 // prepare loop count - beq+ 2f // source already aligned - - sub rs,rs,w3 // word-align source ptr - lwz w2,-4(rs) // get 1st aligned word which we may overwrite - stw w1,-4(rd) // store all 4 bytes to align without a loop - sub rd,rd,w3 - mr w1,w2 // shift 1st aligned source word to w1 - b 2f - -1: - lwz w1,-4(rs) -2: - lwz w2,-8(rs) - lwz w3,-12(rs) - lwzu w4,-16(rs) - stw w1,-4(rd) - stw w2,-8(rd) - stw w3,-12(rd) - stwu w4,-16(rd) - bdnz 1b - - b LShortReverse16 - - -// Long operands. Use branch table to decide which loop to use. -// w1 = (rd-rs), used to determine alignment - -LLong: - xor w4,w1,rc // we must move reverse if (rd-rs)=1) - mtctr r0 // prepare loop count - beq+ 1f // dest already aligned - - lwz w2,0(rs) // get first 4 bytes of source - lwzx w1,w3,rs // get source bytes we might overwrite - add rs,rs,w3 // adjust source ptr - stw w2,0(rd) // store all 4 bytes to avoid a loop - add rd,rd,w3 // word-align destination - b 2f -1: - lwz w1,0(rs) -2: - lwz w2,4(rs) - lwz w3,8(rs) - lwz w4,12(rs) - lwz w5,16(rs) - lwz w6,20(rs) - lwz w7,24(rs) - lwz w8,28(rs) - addi rs,rs,32 - stw w1,0(rd) - stw w2,4(rd) - stw w3,8(rd) - stw w4,12(rd) - stw w5,16(rd) - stw w6,20(rd) - stw w7,24(rd) - stw w8,28(rd) - addi rd,rd,32 - bdnz 1b - - b LShort - - -// G3, forward, long, word aligned. We use floating pt even when only word aligned. -// w1 = neg(rd) - -LForwardFloat: - andi. w3,w1,7 // W3 <- #bytes to doubleword-align destination - mtlr ra // restore return address - sub rc,rc,w3 // adjust count for alignment - srwi r0,rc,5 // number of 32-byte chunks to xfer (>=1) - mtctr r0 // prepare loop count - beq LForwardFloatLoop // dest already aligned - - lwz w1,0(rs) // get first 8 bytes of source - lwz w2,4(rs) - lfdx f0,w3,rs // get source bytes we might overwrite - add rs,rs,w3 // word-align source ptr - stw w1,0(rd) // store all 8 bytes to avoid a loop - stw w2,4(rd) - add rd,rd,w3 - b LForwardFloatLoop1 - - .align 4 // align since this loop is executed by G4s too -LForwardFloatLoop: - lfd f0,0(rs) -LForwardFloatLoop1: // enter here from LMediumAligned and above - lfd f1,8(rs) - lfd f2,16(rs) - lfd f3,24(rs) - addi rs,rs,32 - stfd f0,0(rd) - stfd f1,8(rd) - stfd f2,16(rd) - stfd f3,24(rd) - addi rd,rd,32 - bdnz LForwardFloatLoop - - b LShort - - -// G4 Forward, long, 16-byte aligned, 32-byte cache ops, use DCBA and DCBT. -// r0/cr0 = #bytes to 32-byte align - -LForwardVecAlig32Dcba: - bnel+ LAlign32 // align destination iff necessary - bl LPrepareForwardVectors - mtlr ra // restore return address before loading c128 - li c128,128 - b 1f // enter aligned loop - - .align 5 // long loop heads should be at least 16-byte aligned -1: // loop over aligned 64-byte chunks - dcbt c96,rs // pre-fetch three cache lines ahead - dcbt c128,rs // and four - lvx v1,0,rs - lvx v2,c16,rs - lvx v3,c32,rs - lvx v4,c48,rs - addi rs,rs,64 - dcba 0,rd // avoid read of destination cache lines - stvx v1,0,rd - stvx v2,c16,rd - dcba c32,rd - stvx v3,c32,rd - stvx v4,c48,rd - addi rd,rd,64 - bdnz 1b - -LForwardVectorAlignedEnd: // r0/cr0=#quadwords, rv=VRSave, cr7=low 4 bits of rc, cr6 set on cr7 - beq- 3f // no leftover quadwords - mtctr r0 -2: // loop over remaining quadwords (1-7) - lvx v1,0,rs - addi rs,rs,16 - stvx v1,0,rd - addi rd,rd,16 - bdnz 2b -3: - mtspr VRSave,rv // restore bitmap of live vr's - bne cr6,LShort16 // handle last 0-15 bytes if any - blr - - -// G4 Forward, long, 16-byte aligned, 32-byte cache, use DCBT but not DCBA. -// r0/cr0 = #bytes to 32-byte align - -LForwardVecAlig32NoDcba: - bnel+ LAlign32 // align destination iff necessary - bl LPrepareForwardVectors - mtlr ra // restore return address before loading c128 - li c128,128 - b 1f // enter aligned loop - - .align 4 // balance 13-word loop between QWs... - nop // ...which improves performance 5% +/- - nop -1: // loop over aligned 64-byte chunks - dcbt c96,rs // pre-fetch three cache lines ahead - dcbt c128,rs // and four - lvx v1,0,rs - lvx v2,c16,rs - lvx v3,c32,rs - lvx v4,c48,rs - addi rs,rs,64 - stvx v1,0,rd - stvx v2,c16,rd - stvx v3,c32,rd - stvx v4,c48,rd - addi rd,rd,64 - bdnz 1b - - b LForwardVectorAlignedEnd - - -// G4 Forward, long, unaligned, 32-byte cache ops, use DCBT and DCBA. At least on -// some CPUs, this routine is no slower than the simpler aligned version that does -// not use permutes. But it cannot be used with aligned operands, because of the -// way it prefetches source QWs. -// r0/cr0 = #bytes to 32-byte align - -LForwardVecUnal32Dcba: - bnel+ LAlign32 // align destination iff necessary - bl LPrepareForwardVectors - lvx v1,0,rs // prime loop - mtlr ra // restore return address before loading c128 - lvsl vp,0,rs // get permute vector to shift left - li c128,128 - b 1f // enter aligned loop - - .align 4 // long loop heads should be at least 16-byte aligned -1: // loop over aligned 64-byte destination chunks - lvx v2,c16,rs - dcbt c96,rs // touch 3rd cache line ahead - lvx v3,c32,rs - dcbt c128,rs // touch 4th cache line ahead - lvx v4,c48,rs - addi rs,rs,64 - vperm vx,v1,v2,vp - lvx v1,0,rs - vperm vy,v2,v3,vp - dcba 0,rd // avoid read of destination lines - stvx vx,0,rd - vperm vz,v3,v4,vp - stvx vy,c16,rd - dcba c32,rd - vperm vx,v4,v1,vp - stvx vz,c32,rd - stvx vx,c48,rd - addi rd,rd,64 - bdnz 1b - -LForwardVectorUnalignedEnd: // r0/cr0=#QWs, rv=VRSave, v1=next QW, cr7=(rc & F), cr6 set on cr7 - beq- 3f // no leftover quadwords - mtctr r0 -2: // loop over remaining quadwords - lvx v2,c16,rs - addi rs,rs,16 - vperm vx,v1,v2,vp - vor v1,v2,v2 // v1 <- v2 - stvx vx,0,rd - addi rd,rd,16 - bdnz 2b -3: - mtspr VRSave,rv // restore bitmap of live vr's - bne cr6,LShort16 // handle last 0-15 bytes if any - blr - - -// G4 Forward, long, unaligned, 32-byte cache ops, use DCBT but not DCBA. -// r0/cr0 = #bytes to 32-byte align - -LForwardVecUnal32NoDcba: - bnel+ LAlign32 // align destination iff necessary - bl LPrepareForwardVectors - lvx v1,0,rs // prime loop - mtlr ra // restore return address before loading c128 - lvsl vp,0,rs // get permute vector to shift left - li c128,128 - b 1f // enter aligned loop - - .align 4 - nop // balance 17-word loop between QWs - nop -1: // loop over aligned 64-byte destination chunks - lvx v2,c16,rs - dcbt c96,rs // touch 3rd cache line ahead - lvx v3,c32,rs - dcbt c128,rs // touch 4th cache line ahead - lvx v4,c48,rs - addi rs,rs,64 - vperm vx,v1,v2,vp - lvx v1,0,rs - vperm vy,v2,v3,vp - stvx vx,0,rd - vperm vz,v3,v4,vp - stvx vy,c16,rd - vperm vx,v4,v1,vp - stvx vz,c32,rd - stvx vx,c48,rd - addi rd,rd,64 - bdnz 1b - - b LForwardVectorUnalignedEnd - - -// G3 Reverse, long, unaligned. - -LReverseWord: - bl LAlign8Reverse // 8-byte align destination - mtlr ra // restore return address - srwi r0,rc,5 // get count of 32-byte chunks to xfer (> 1) - mtctr r0 -1: - lwz w1,-4(rs) - lwz w2,-8(rs) - lwz w3,-12(rs) - lwz w4,-16(rs) - stw w1,-4(rd) - lwz w5,-20(rs) - stw w2,-8(rd) - lwz w6,-24(rs) - stw w3,-12(rd) - lwz w7,-28(rs) - stw w4,-16(rd) - lwzu w8,-32(rs) - stw w5,-20(rd) - stw w6,-24(rd) - stw w7,-28(rd) - stwu w8,-32(rd) - bdnz 1b - - b LShortReverse - - -// G3 Reverse, long, word aligned. - -LReverseFloat: - bl LAlign8Reverse // 8-byte align - mtlr ra // restore return address - srwi r0,rc,5 // get count of 32-byte chunks to xfer (> 1) - mtctr r0 -1: - lfd f0,-8(rs) - lfd f1,-16(rs) - lfd f2,-24(rs) - lfdu f3,-32(rs) - stfd f0,-8(rd) - stfd f1,-16(rd) - stfd f2,-24(rd) - stfdu f3,-32(rd) - bdnz 1b - - b LShortReverse - - -// G4 Reverse, long, 16-byte aligned, 32-byte DCBT but no DCBA. - -LReverseVectorAligned32: - bl LAlign32Reverse // 32-byte align destination iff necessary - bl LPrepareReverseVectors - mtlr ra // restore return address before loading cm129 - li cm129,-129 - b 1f // enter aligned loop - - .align 4 - nop // must start in 3rd word of QW... - nop // ...to keep balanced -1: // loop over aligned 64-byte chunks - dcbt cm97,rs // pre-fetch three cache lines ahead - dcbt cm129,rs // and four - lvx v1,cm1,rs - lvx v2,cm17,rs - lvx v3,cm33,rs - lvx v4,cm49,rs - subi rs,rs,64 - stvx v1,cm1,rd - stvx v2,cm17,rd - stvx v3,cm33,rd - stvx v4,cm49,rd - subi rd,rd,64 - bdnz 1b - -LReverseVectorAlignedEnd: // cr0/r0=#quadwords, rv=VRSave, cr7=low 4 bits of rc, cr6 set on cr7 - beq 3f // no leftover quadwords - mtctr r0 -2: // loop over 1-3 quadwords - lvx v1,cm1,rs - subi rs,rs,16 - stvx v1,cm1,rd - subi rd,rd,16 - bdnz 2b -3: - mtspr VRSave,rv // restore bitmap of live vr's - bne cr6,LShortReverse16 // handle last 0-15 bytes iff any - blr - - -// G4 Reverse, long, unaligned, 32-byte DCBT. - -LReverseVectorUnal32: - bl LAlign32Reverse // align destination iff necessary - bl LPrepareReverseVectors - lvx v1,cm1,rs // prime loop - mtlr ra // restore return address before loading cm129 - lvsl vp,0,rs // get permute vector to shift left - li cm129,-129 - b 1f // enter aligned loop - - .align 4 - nop // start loop in 3rd word on QW to balance - nop -1: // loop over aligned 64-byte destination chunks - lvx v2,cm17,rs - dcbt cm97,rs // touch in 3rd source block - lvx v3,cm33,rs - dcbt cm129,rs // touch in 4th - lvx v4,cm49,rs - subi rs,rs,64 - vperm vx,v2,v1,vp - lvx v1,cm1,rs - vperm vy,v3,v2,vp - stvx vx,cm1,rd - vperm vz,v4,v3,vp - stvx vy,cm17,rd - vperm vx,v1,v4,vp - stvx vz,cm33,rd - stvx vx,cm49,rd - subi rd,rd,64 - bdnz 1b - -LReverseVectorUnalignedEnd: // r0/cr0=#QWs, rv=VRSave, v1=source QW, cr7=low 4 bits of rc, cr6 set on cr7 - beq 3f // no leftover quadwords - mtctr r0 -2: // loop over 1-3 quadwords - lvx v2,cm17,rs - subi rs,rs,16 - vperm vx,v2,v1,vp - vor v1,v2,v2 // v1 <- v2 - stvx vx,cm1,rd - subi rd,rd,16 - bdnz 2b -3: - mtspr VRSave,rv // restore bitmap of live vr's - bne cr6,LShortReverse16 // handle last 0-15 bytes iff any - blr - - -// Subroutine to prepare for 64-byte forward vector loops. -// Returns many things: -// ctr = number of 64-byte chunks to move -// r0/cr0 = leftover QWs to move -// cr7 = low 4 bits of rc (ie, leftover byte count 0-15) -// cr6 = beq if leftover byte count is 0 -// c16..c96 loaded -// rv = original value of VRSave -// NB: c128 not set (if needed), since it is still "ra" - -LPrepareForwardVectors: - mfspr rv,VRSave // get bitmap of live vector registers - srwi r0,rc,6 // get count of 64-byte chunks to move (>=1) - oris w1,rv,0xFF00 // we use v0-v7 - mtcrf 0x01,rc // prepare for moving last 0-15 bytes in LShort16 - rlwinm w3,rc,0,28,31 // move last 0-15 byte count to w3 too - mtspr VRSave,w1 // update mask - li c16,16 // get constants used in ldvx/stvx - li c32,32 - mtctr r0 // set up loop count - cmpwi cr6,w3,0 // set cr6 on leftover byte count - li c48,48 - li c96,96 - rlwinm. r0,rc,28,30,31 // get number of quadword leftovers (0-3) and set cr0 - blr - - -// Subroutine to prepare for 64-byte reverse vector loops. -// Returns many things: -// ctr = number of 64-byte chunks to move -// r0/cr0 = leftover QWs to move -// cr7 = low 4 bits of rc (ie, leftover byte count 0-15) -// cr6 = beq if leftover byte count is 0 -// cm1..cm97 loaded -// rv = original value of VRSave -// NB: cm129 not set (if needed), since it is still "ra" - -LPrepareReverseVectors: - mfspr rv,VRSave // get bitmap of live vector registers - srwi r0,rc,6 // get count of 64-byte chunks to move (>=1) - oris w1,rv,0xFF00 // we use v0-v7 - mtcrf 0x01,rc // prepare for moving last 0-15 bytes in LShortReverse16 - rlwinm w3,rc,0,28,31 // move last 0-15 byte count to w3 too - mtspr VRSave,w1 // update mask - li cm1,-1 // get constants used in ldvx/stvx - li cm17,-17 - mtctr r0 // set up loop count - cmpwi cr6,w3,0 // set cr6 on leftover byte count - li cm33,-33 - li cm49,-49 - rlwinm. r0,rc,28,30,31 // get number of quadword leftovers (0-3) and set cr0 - li cm97,-97 - blr - - -// Subroutine to align destination on a 32-byte boundary. -// r0 = number of bytes to xfer (0-31) - -LAlign32: - mtcrf 0x01,r0 // length to cr (faster to change 1 CR at a time) - mtcrf 0x02,r0 - sub rc,rc,r0 // adjust length - bf 31,1f // skip if no odd bit - lbz w1,0(rs) - addi rs,rs,1 - stb w1,0(rd) - addi rd,rd,1 -1: - bf 30,2f // halfword to move? - lhz w1,0(rs) - addi rs,rs,2 - sth w1,0(rd) - addi rd,rd,2 -2: - bf 29,3f // word? - lwz w1,0(rs) - addi rs,rs,4 - stw w1,0(rd) - addi rd,rd,4 -3: - bf 28,4f // doubleword? - lwz w1,0(rs) - lwz w2,4(rs) - addi rs,rs,8 - stw w1,0(rd) - stw w2,4(rd) - addi rd,rd,8 -4: - bflr 27 // done if no quadword to move - lwz w1,0(rs) - lwz w2,4(rs) - lwz w3,8(rs) - lwz w4,12(rs) - addi rs,rs,16 - stw w1,0(rd) - stw w2,4(rd) - stw w3,8(rd) - stw w4,12(rd) - addi rd,rd,16 - blr - -// Subroutine to align destination if necessary on a 32-byte boundary for reverse moves. -// rs and rd still point to low end of operands -// we adjust rs and rd to point to last byte moved - -LAlign32Reverse: - add rd,rd,rc // point to last byte moved (ie, 1 past end of operands) - add rs,rs,rc - andi. r0,rd,0x1F // r0 <- #bytes that must be moved to align destination - mtcrf 0x01,r0 // length to cr (faster to change 1 CR at a time) - mtcrf 0x02,r0 - sub rc,rc,r0 // update length - beqlr- // destination already 32-byte aligned - - bf 31,1f // odd byte? - lbzu w1,-1(rs) - stbu w1,-1(rd) -1: - bf 30,2f // halfword to move? - lhzu w1,-2(rs) - sthu w1,-2(rd) -2: - bf 29,3f // word? - lwzu w1,-4(rs) - stwu w1,-4(rd) -3: - bf 28,4f // doubleword? - lwz w1,-4(rs) - lwzu w2,-8(rs) - stw w1,-4(rd) - stwu w2,-8(rd -4: - bflr 27 // done if no quadwords - lwz w1,-4(rs) - lwz w2,-8(rs) - lwz w3,-12(rs) - lwzu w4,-16(rs) - stw w1,-4(rd) - stw w2,-8(rd) - stw w3,-12(rd) - stwu w4,-16(rd) - blr - - -// Subroutine to align destination on an 8-byte boundary for reverse moves. -// rs and rd still point to low end of operands -// we adjust rs and rd to point to last byte moved - -LAlign8Reverse: - add rd,rd,rc // point to last byte moved (ie, 1 past end of operands) - add rs,rs,rc - andi. r0,rd,0x7 // r0 <- #bytes that must be moved to align destination - beqlr- // destination already 8-byte aligned - mtctr r0 // set up for loop - sub rc,rc,r0 // update length -1: - lbzu w1,-1(rs) - stbu w1,-1(rd) - bdnz 1b - - blr - - -// Called by pthread initialization to set up the branch table pointer based on -// the CPU capability vector. This routine may be called more than once (for -// example, during testing.) - -// Size of the buffer we use to do DCBA timing on G4: -#define kBufSiz 1024 - -// Stack frame size, which contains the 128-byte-aligned buffer: -#define kSFSize (kBufSiz+128+16) - -// Iterations of the timing loop: -#define kLoopCnt 5 - -// Bit in cr5 used as a flag in timing loop: -#define kDCBA 22 - -__bcopy_initialize: // int _bcopy_initialize(void) - mflr ra // get return - stw ra,8(r1) // save - stwu r1,-kSFSize(r1) // carve our temp buffer from the stack - addi w6,r1,127+16 // get base address... - rlwinm w6,w6,0,0,24 // ...of our buffer, 128-byte aligned - bcl 20,31,1f // get our PIC base -1: - mflr w1 - addis w2,w1,ha16(__cpu_capabilities - 1b) - lwz w3,lo16(__cpu_capabilities - 1b)(w2) - andi. r0,w3,kUseDcba+kNoDcba+kCache32+k64Bit+kHasAltivec - cmpwi r0,kCache32+kHasAltivec // untyped G4? - li w8,0 // assume no need to test - bne 2f // not an untyped G4, so do not test - - // G4, but neither kUseDcba or kNoDcba are set. Time and select fastest. - - crset kDCBA // first, use DCBA - bl LTest32 // time it - mr w8,w4 // w8 <- best time using DCBA - srwi r0,w8,3 // bias 12 pct in favor of not using DCBA... - add w8,w8,r0 // ...because DCBA is always slower with warm cache - crclr kDCBA - bl LTest32 // w4 <- best time without DCBA - cmplw w8,w4 // which is better? - li w8,kUseDcba // assume using DCBA is faster - blt 2f - li w8,kNoDcba // no DCBA is faster - - // What branch table to use? - -2: // here with w8 = 0, kUseDcba, or kNoDcba - bcl 20,31,4f // get our PIC base again -4: - mflr w1 - addis w2,w1,ha16(__cpu_capabilities - 4b) - lwz w3,lo16(__cpu_capabilities - 4b)(w2) - or w3,w3,w8 // add in kUseDcba or kNoDcba if untyped G4 - mr r3,w8 // return dynamic selection, if any (used in testing) - - andi. r0,w3,kHasAltivec+k64Bit+kCache128+kCache64+kCache32+kUseDcba+kNoDcba - cmpwi r0,kHasAltivec+kCache32+kUseDcba // G4 with DCBA? - addis w4,w1,ha16(LG4UseDcba - 4b) - addi w4,w4,lo16(LG4UseDcba - 4b) - beq 5f - - andi. r0,w3,kHasAltivec+k64Bit+kCache128+kCache64+kCache32+kUseDcba+kNoDcba - cmpwi r0,kHasAltivec+kCache32+kNoDcba // G4 without DCBA? - addis w4,w1,ha16(LG4NoDcba - 4b) - addi w4,w4,lo16(LG4NoDcba - 4b) - beq 5f - - andi. r0,w3,kHasAltivec+k64Bit+kCache128+kCache64+kCache32 - cmpwi r0,kCache32 // G3? - addis w4,w1,ha16(LG3 - 4b) - addi w4,w4,lo16(LG3 - 4b) - beq 5f - - // Map unrecognized CPU types to G3 (lowest common denominator) - -5: // w4 <- branch table pointer - addis w5,w1,ha16(LBranchTablePtr - 4b) - stw w4,lo16(LBranchTablePtr - 4b)(w5) - lwz ra,kSFSize+8(r1) // recover return address - mtlr ra // restore it - lwz r1,0(r1) // pop off our stack frame - blr // return dynamic selection (or 0) in r3 - - -// Subroutine to time a 32-byte cache. -// kDCBA = set if we should use DCBA -// w6 = base of buffer to use for test (kBufSiz bytes) -// w4 = we return time of fastest loop in w4 - -LTest32: - li w1,kLoopCnt // number of times to loop - li w4,-1 // initialize fastest time -1: - mr rd,w6 // initialize buffer ptr - li r0,kBufSiz/32 // r0 <- cache blocks to test - mtctr r0 -2: - dcbf 0,rd // first, force the blocks out of the cache - addi rd,rd,32 - bdnz 2b - sync // make sure all the flushes take - mr rd,w6 // re-initialize buffer ptr - mtctr r0 // reset cache-block count - mftbu w5 // remember upper half so we can check for carry - mftb w2 // start the timer -3: // loop over cache blocks - bf kDCBA,4f // should we DCBA? - dcba 0,rd -4: - stfd f1,0(rd) // store the entire cache block - stfd f1,8(rd) - stfd f1,16(rd) - stfd f1,24(rd) - addi rd,rd,32 - bdnz 3b - mftb w3 - mftbu r0 - cmpw r0,w5 // did timebase carry? - bne 1b // yes, retest rather than fuss - sub w3,w3,w2 // w3 <- time for this loop - cmplw w3,w4 // faster than current best? - bge 5f // no - mr w4,w3 // remember fastest time through loop -5: - subi w1,w1,1 // decrement outer loop count - cmpwi w1,0 // more to go? - bne 1b // loop if so - blr - \ No newline at end of file + ba _COMM_PAGE_MEMCPY + diff --git a/ppc/gen/bzero.s b/ppc/gen/bzero.s index 1a04b69..2bd14ee 100644 --- a/ppc/gen/bzero.s +++ b/ppc/gen/bzero.s @@ -42,6 +42,9 @@ #define rp r11 #define rv r10 +#define __APPLE_API_PRIVATE +#include + #include .text @@ -54,84 +57,36 @@ // ************* _bzero: // void bzero(void *b, size_t len); - cmplwi cr1,rc,32 // too short for DCBZ? - li rv,0 // get a 0 -Lbzero1: // enter from memset with cr1 and rv set up - neg r5,r3 // start to compute bytes to align - mr rp,r3 // make copy of operand ptr - andi. r6,r5,0x1F // r6 <- bytes to align on cache block - blt- cr1,Ltail // <32, so skip DCBZs - beq- cr0,Ldcbz // already aligned - - // align on 32-byte boundary - - mtcrf 0x01,r6 // move length to cr7 (faster if only 1 cr) - andi. r7,r6,16 // test bit 27 by hand - sub rc,rc,r6 // adjust length - bf 31,1f // test bits of count - stb rv,0(rp) - addi rp,rp,1 -1: - bf 30,2f - sth rv,0(rp) - addi rp,rp,2 -2: - bf 29,3f - stw rv,0(rp) - addi rp,rp,4 -3: - bf 28,4f - stw rv,0(rp) - stw rv,4(rp) - addi rp,rp,8 -4: - beq Ldcbz - stw rv,0(rp) - stw rv,4(rp) - stw rv,8(rp) - stw rv,12(rp) - addi rp,rp,16 - - // DCBZ 32-byte cache blocks -Ldcbz: - srwi. r5,rc,5 // r5 <- number of cache blocks to zero - beq Ltail // none - mtctr r5 // set up loop count - andi. rc,rc,0x1F // will there be leftovers? -1: - dcbz 0,rp // zero 32 bytes - addi rp,rp,32 - bdnz 1b - beqlr // no leftovers so done - - // store up to 31 trailing bytes - // rv = value to store (in all 4 bytes) - // rc = #bytes to store (0..31) + ba _COMM_PAGE_BZERO + + // store up to 31 trailing bytes + // rv = value to store (in all 4 bytes) + // rc = #bytes to store (0..31) Ltail: - andi. r5,rc,16 // bit 27 set in length? - mtcrf 0x01,rc // low 4 bits of length to cr7 - beq 1f // test bits of length - stw rv,0(rp) - stw rv,4(rp) - stw rv,8(rp) - stw rv,12(rp) - addi rp,rp,16 + andi. r5,rc,16 // bit 27 set in length? + mtcrf 0x01,rc // low 4 bits of length to cr7 + beq 1f // test bits of length + stw rv,0(rp) + stw rv,4(rp) + stw rv,8(rp) + stw rv,12(rp) + addi rp,rp,16 1: - bf 28,2f - stw rv,0(rp) - stw rv,4(rp) - addi rp,rp,8 + bf 28,2f + stw rv,0(rp) + stw rv,4(rp) + addi rp,rp,8 2: - bf 29,3f - stw rv,0(rp) - addi rp,rp,4 + bf 29,3f + stw rv,0(rp) + addi rp,rp,4 3: - bf 30,4f - sth rv,0(rp) - addi rp,rp,2 + bf 30,4f + sth rv,0(rp) + addi rp,rp,2 4: - bflr 31 - stb rv,0(rp) + bflr 31 + stb rv,0(rp) blr @@ -144,7 +99,7 @@ _memset: // void * memset(void *b, int c, size_t len); andi. rv,r4,0xFF // copy value to working register, test for 0 mr rc,r5 // move length to working register cmplwi cr1,r5,32 // length < 32 ? - beq Lbzero1 // memset of 0 is just a bzero + beqa++ _COMM_PAGE_BZERO rlwimi rv,rv,8,16,23 // replicate value to low 2 bytes mr rp,r3 // make working copy of operand ptr rlwimi rv,rv,16,0,15 // value now in all 4 bytes @@ -202,4 +157,4 @@ Lmemset1: 5: bflr 31 stb rv,0(rp) - blr + blr diff --git a/ppc/gen/icacheinval.s b/ppc/gen/icacheinval.s new file mode 100644 index 0000000..69ec1a9 --- /dev/null +++ b/ppc/gen/icacheinval.s @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + +/* sys_icache_invalidate(char *start, long len) */ +/* this routine has moved to the comm page */ + + .text + .globl _sys_icache_invalidate + .align 2 +_sys_icache_invalidate: + ba _COMM_PAGE_FLUSH_ICACHE diff --git a/ppc/gen/insque.c b/ppc/gen/insque.c deleted file mode 100644 index 101daa5..0000000 --- a/ppc/gen/insque.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/insque.c - * - * struct qelem { - * struct qelem *q_forw; - * struct qelem *q_back; - * char q_data[]; - * }; - * - * void insque(struct qelem *elem, struct qelem *prev); - * - * Inserts queue entry `elem' into a queue after element `prev'. - * - * HISTORY -* 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) -* Ported to PPC. - * 10-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#include - -void -insque(struct qelem *elem, struct qelem *prev) -{ - struct qelem *next; - - next = prev->q_forw; - prev->q_forw = elem; - if (next != 0) - next->q_back = elem; - elem->q_forw = next; - elem->q_back = prev; -} diff --git a/ppc/gen/remque.c b/ppc/gen/remque.c deleted file mode 100644 index 380c7f2..0000000 --- a/ppc/gen/remque.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/remque.c - * - * struct qelem { - * struct qelem *q_forw; - * struct qelem *q_back; - * char q_data[]; - * }; - * - * void remque(struct qelem *entry); - * - * Removes `entry' from a queue. - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 10-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import - -void -remque(struct qelem *elem) -{ - struct qelem *next, *prev; - - next = elem->q_forw; - prev = elem->q_back; - if (next != 0) - next->q_back = prev; - if (prev != 0) - prev->q_forw = next; -} diff --git a/ppc/gen/setjmperr.c b/ppc/gen/setjmperr.c index 0926322..4b9ec69 100644 --- a/ppc/gen/setjmperr.c +++ b/ppc/gen/setjmperr.c @@ -28,6 +28,9 @@ * specifies the terms and conditions for redistribution. */ +#include +#include + #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)setjmperr.c 5.2 (Berkeley) 3/9/86"; #endif LIBC_SCCS and not lint diff --git a/ppc/gen/strcat.c b/ppc/gen/strcat.c deleted file mode 100644 index be23a09..0000000 --- a/ppc/gen/strcat.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/strcat.c - * Author: Mike DeMoney, NeXT Software, Inc. - * - * This file contains machine dependent code for string copy - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 9-Nov-92 Derek B Clegg (dclegg@next.com) - * Ported to m98k. - * 4-Jun-91 Mike DeMoney (mike@next.com) - * Created. - */ -#import - -char * -strcat(char *s1, const char *s2) -{ - strcpy(&s1[strlen(s1)], s2); - return s1; -} diff --git a/ppc/gen/strcmp.c b/ppc/gen/strcmp.c deleted file mode 100644 index 8d8a78d..0000000 --- a/ppc/gen/strcmp.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/strcmp.c - * - * This file contains machine dependent code for string comparison - * on NeXT 88K-based products. - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import - -/* This routine should be optimized. */ - -/* ANSI sez: - * The `strcmp' function compares the string pointed to by `s1' to the - * string pointed to by `s2'. - * The `strcmp' function returns an integer greater than, equal to, or less - * than zero, according as the string pointed to by `s1' is greater than, - * equal to, or less than the string pointed to by `s2'. [4.11.4.2] - */ -int -strcmp(const char *s1, const char *s2) -{ - for ( ; *s1 == *s2; s1++, s2++) - if (*s1 == '\0') - return 0; - return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); -} diff --git a/ppc/gen/strcpy.c b/ppc/gen/strcpy.c deleted file mode 100644 index 54c1dbc..0000000 --- a/ppc/gen/strcpy.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/strcpy.c - * - * This file contains machine dependent code for string copy - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import - -/* XXX This routine should be optimized. */ - -/* ANSI sez: - * The `strcpy' function copies the string pointed to by `s2' (including - * the terminating null character) into the array pointed to by `s1'. - * If copying takes place between objects that overlap, the behavior - * is undefined. - * The `strcpy' function returns the value of `s1'. [4.11.2.3] - */ -char * -strcpy(char *s1, const char *s2) -{ - char *s = s1; - while ((*s++ = *s2++) != 0) - ; - return (s1); -} diff --git a/ppc/gen/strncat.c b/ppc/gen/strncat.c deleted file mode 100644 index 15f25eb..0000000 --- a/ppc/gen/strncat.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/strncat.c - * Author: Mike DeMoney, NeXT Software, Inc. - * - * This file contains machine dependent code for string copy - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 23-Nov-92 Derek B Clegg (dclegg@next.com) - * Ported to m98k. - * 4-Jun-91 Mike DeMoney (mike@next.com) - * Created. - */ -#import - -char * -strncat(char *s1, const char *s2, size_t n) -{ - unsigned len1 = strlen(s1); - unsigned len2 = strlen(s2); - - if (len2 < n) { - strcpy(&s1[len1], s2); - } else { - strncpy(&s1[len1], s2, n); - s1[len1 + n] = '\0'; - } - return s1; -} diff --git a/ppc/gen/strncmp.c b/ppc/gen/strncmp.c deleted file mode 100644 index 51b16f8..0000000 --- a/ppc/gen/strncmp.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/strncmp.c - * - * This file contains machine dependent code for string comparison - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import - -/* This routine should be optimized. */ - -/* ANSI sez: - * The `strncmp' function compares not more than `n' characters (characters - * that follow a null character are not compared) from the array pointed to - * by `s1' to the array pointed to by `s2'. - * The `strncmp' function returns an integer greater than, equal to, or less - * than zero, according as the possibly null-terminated array pointed to by - * `s1' is greater than, equal to, or less than the possibly null-terminated - * array pointed to by `s2'. [4.11.4.4] - */ -int -strncmp(const char *s1, const char *s2, size_t n) -{ - for ( ; n > 0; s1++, s2++, --n) - if (*s1 != *s2) - return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); - else if (*s1 == '\0') - return 0; - return 0; -} diff --git a/ppc/gen/strncpy.c b/ppc/gen/strncpy.c deleted file mode 100644 index 10ca272..0000000 --- a/ppc/gen/strncpy.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1997 NeXT Software, Inc. All rights reserved. - * - * File: libc/gen/ppc/strncpy.c - * - * This file contains machine dependent code for string copy - * - * HISTORY - * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) - * Ported to PPC. - * 24-Nov-92 Derek B Clegg (dclegg@next.com) - * Created. - */ -#import - -/* This routine should be optimized. */ - -/* ANSI sez: - * The `strncpy' function copies not more than `n' characters (characters - * that follow a null character are not copied) from the array pointed to - * by `s2' to the array pointed to by `s1'. If copying takes place between - * objects that overlap, the behavior is undefined. - * If the array pointed to by `s2' is a string that is shorter than `n' - * characters, null characters are appended to the copy in the array - * pointed to by `s1', until `n' characters in all have been written. - * The `strncpy' function returns the value of `s1'. [4.11.2.4] - */ -char * -strncpy(char *s1, const char *s2, size_t n) -{ - char *s = s1; - while (n > 0 && *s2 != '\0') { - *s++ = *s2++; - --n; - } - while (n > 0) { - *s++ = '\0'; - --n; - } - return s1; -} diff --git a/ppc/mach/mach_absolute_time.s b/ppc/mach/mach_absolute_time.s index 5f35df3..52f3fbc 100644 --- a/ppc/mach/mach_absolute_time.s +++ b/ppc/mach/mach_absolute_time.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,15 +23,12 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if defined(__ppc__) +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + .text -.align 2 +.align 4 .globl _mach_absolute_time _mach_absolute_time: -1: mftbu r3 - mftb r4 - mftbu r0 - cmpw r0,r3 - bne- 1b - blr -#endif + ba _COMM_PAGE_ABSOLUTE_TIME diff --git a/ppc/pthreads/Makefile.inc b/ppc/pthreads/Makefile.inc new file mode 100644 index 0000000..f4f5b0a --- /dev/null +++ b/ppc/pthreads/Makefile.inc @@ -0,0 +1,6 @@ +MDSRCS += \ + init_cpu_capabilities.c \ + get_cpu_capabilities.s \ + pthread_set_self.s \ + pthread_self.s \ + pthread_getspecific.s diff --git a/ppc/pthreads/get_cpu_capabilities.s b/ppc/pthreads/get_cpu_capabilities.s new file mode 100644 index 0000000..6b795a7 --- /dev/null +++ b/ppc/pthreads/get_cpu_capabilities.s @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* Get the cpu_capabilities bit vector out of the comm page */ + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + +.text +.align 2 +.private_extern __get_cpu_capabilities +__get_cpu_capabilities: + lwz r3, _COMM_PAGE_CPU_CAPABILITIES(0) + blr diff --git a/ppc/pthreads/init_cpu_capabilities.c b/ppc/pthreads/init_cpu_capabilities.c new file mode 100644 index 0000000..e9de34d --- /dev/null +++ b/ppc/pthreads/init_cpu_capabilities.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* Initialize the "_cpu_capabilities" vector on PowerPC processors. */ + +#define __APPLE_API_PRIVATE +#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 + +__private_extern__ void +_init_cpu_capabilities( void ) +{ + int temp = _get_cpu_capabilities(); + _cpu_capabilities = temp; + + _cpu_has_altivec = (temp & kHasAltivec) ? 1 : 0; +} diff --git a/ppc/pthreads/pthread_getspecific.s b/ppc/pthreads/pthread_getspecific.s new file mode 100644 index 0000000..27af77c --- /dev/null +++ b/ppc/pthreads/pthread_getspecific.s @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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" + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + + .text + .align 4 + .globl _pthread_getspecific +_pthread_getspecific: + li r4,_PTHREAD_TSD_OFFSET + ba _COMM_PAGE_PTHREAD_GETSPECIFIC diff --git a/ppc/pthreads/pthread_self.s b/ppc/pthreads/pthread_self.s new file mode 100644 index 0000000..a64ecf2 --- /dev/null +++ b/ppc/pthreads/pthread_self.s @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + + .text + .align 2 + .globl _pthread_self +_pthread_self: + ba _COMM_PAGE_PTHREAD_SELF diff --git a/ppc/sys/cthread.s b/ppc/pthreads/pthread_set_self.s similarity index 89% rename from ppc/sys/cthread.s rename to ppc/pthreads/pthread_set_self.s index 0af0e73..b4f6dcb 100644 --- a/ppc/sys/cthread.s +++ b/ppc/pthreads/pthread_set_self.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,8 +24,8 @@ */ .text .align 2 - .globl __pthread_set_self -__pthread_set_self: + .globl ___pthread_set_self +___pthread_set_self: li r0, 0x7FF1 sc blr diff --git a/ppc/stdlib/gdtoa.mk b/ppc/stdlib/gdtoa.mk new file mode 100644 index 0000000..2d49c37 --- /dev/null +++ b/ppc/stdlib/gdtoa.mk @@ -0,0 +1,2 @@ +# Long double is just double precision. +FBSDSRCS+=machdep_ldisd.c diff --git a/ppc/string/Makefile.inc b/ppc/string/Makefile.inc new file mode 100644 index 0000000..383a7ba --- /dev/null +++ b/ppc/string/Makefile.inc @@ -0,0 +1,18 @@ +# $Version$ +# +# PPC-optimised string functions. +# +MDSRCS += \ + memcmp.s \ + strcat.s \ + strcmp.s \ + strcpy.s \ + strlcat.s \ + strlcpy.s \ + strlen.s \ + strncat.s \ + strncmp.s \ + strncpy.s + +SUPPRESSSRCS += bcmp.c + diff --git a/ppc/string/memcmp.s b/ppc/string/memcmp.s new file mode 100644 index 0000000..11e2254 --- /dev/null +++ b/ppc/string/memcmp.s @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER // we need the defs for cr7_eq etc +#include +#undef ASSEMBLER + +// *************** *********** +// * M E M C M P * and * B C M P * +// *************** *********** +// +// int memcmp(const char *s1, const char *s2, size_t len); +// int bcmp(const char *s1, const char *s2, size_t len); +// +// Bcmp returns (+,0,-), whereas memcmp returns the true difference +// between the first differing bytes, but we treat them identically. +// +// We optimize the compare by doing it word parallel. This introduces +// a complication: if we blindly did word loads from both sides until +// finding a difference, we might get a spurious page fault by +// reading bytes past the difference. To avoid this, we never do a "lwz" +// that crosses a page boundary. + + .text + .globl EXT(memcmp) + .globl EXT(bcmp) + + .align 5 +LEXT(memcmp) // int memcmp(const char *s1,const char *s2,size_t len); +LEXT(bcmp) // int bcmp(const char *s1,const char *s2,size_t len); + cmplwi cr1,r5,8 // is buffer too short to bother with word compares? + andi. r0,r3,3 // is LHS word aligned? + blt cr1,Lshort // short buffer, so just compare byte-by-byte + beq Laligned // skip if aligned + subfic r0,r0,4 // r0 <- #bytes to word align LHS + mtctr r0 // set up for byte loop + b Lbyteloop + +// Handle short buffer or end-of-buffer. +// r3 = LHS ptr (unaligned) +// r4 = RHS ptr (unaligned) +// r5 = length remaining in buffer (0..7) + +Lshort: + cmpwi r5,0 // null buffer? + mtctr r5 // assume not null, and set up for loop + bne Lshortloop // buffer not null + li r3,0 // say "equal" + blr + + .align 5 +Lshortloop: + lbz r7,0(r3) // next LHS byte + addi r3,r3,1 + lbz r8,0(r4) // next RHS byte + addi r4,r4,1 + cmpw r7,r8 // compare the bytes + bdnzt eq,Lshortloop // loop if more to go and bytes are equal + + sub r3,r7,r8 // generate return value + blr + +// We're at a RHS page boundary. Compare 4 bytes in order to cross the +// page but still keep the LHS ptr word-aligned. + +Lcrosspage: + cmplwi r5,8 // enough bytes left to use word compares? + li r0,4 // get #bytes to cross RHS page + blt Lshort // buffer is about to end + mtctr r0 // set up to compare 4 bytes + b Lbyteloop + +// Compare byte-by-byte. +// r3 = LHS ptr (unaligned) +// r4 = RHS ptr (unaligned) +// r5 = length remaining in buffer (must be >0) +// ctr = bytes to compare + + .align 5 +Lbyteloop: + lbz r7,0(r3) // next LHS byte + addi r3,r3,1 + lbz r8,0(r4) // next RHS byte + addi r4,r4,1 + subi r5,r5,1 // decrement bytes remaining in buffer + cmpw r7,r8 // compare the bytes + bdnzt eq,Lbyteloop // loop if more to go and bytes are equal + + bne Ldifferent // done if we found differing bytes + +// LHS is now word aligned. Loop over words until end of RHS page or buffer. +// When we get to the end of the page, we compare 4 bytes, so that we keep +// the LHS word aligned. +// r3 = LHS ptr (aligned) +// r4 = RHS ptr (unaligned) +// r5 = length remaining in buffer (>= 4 bytes) + +Laligned: + rlwinm r9,r4,0,0xFFF // get RHS offset in page + subfic r0,r9,4096 // get #bytes left in RHS page + subfc r7,r0,r5 // *** + subfe r8,r5,r5 // * r9 <- min(r0,r5), + and r7,r7,r8 // * using algorithm in Compiler Writer's Guide + add r9,r0,r7 // *** + srwi. r8,r9,2 // get #words we can compare + rlwinm r9,r9,0,0,29 // get #bytes we will compare word-parallel + beq-- Lcrosspage // we're at a RHS page boundary + mtctr r8 // set up loop count + sub r5,r5,r9 // decrement length remaining + b Lwordloop + +// Compare a word at a time, until one of two conditions: +// - a difference is found +// - end of count (ie, end of buffer or RHS page, whichever is first) +// At this point, registers are as follows: +// r3 = LHS ptr (aligned) +// r4 = RHS ptr (unaligned) +// r5 = length remaining in buffer (may be 0) +// ctr = count of words until end of buffer or RHS page + + .align 5 // align inner loop, which is 8 words long +Lwordloop: + lwz r7,0(r3) // r7 <- next 4 LHS bytes + addi r3,r3,4 + lwz r8,0(r4) // r8 <- next 4 RHS bytes + addi r4,r4,4 + xor. r11,r7,r8 // compare the words + bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq + + beq-- Lcrosspage // skip if buffer or page end reached + +// Found differing bytes. + + cntlzw r0,r11 // find 1st difference (r0 = 0..31) + rlwinm r9,r0,0,0x18 // byte align bit offset (r9 = 0,8,16, or 24) + addi r0,r9,8 // now, r0 = 8, 16, 24, or 32 + rlwnm r7,r7,r0,24,31 // right justify differing bytes and mask off rest + rlwnm r8,r8,r0,24,31 + +Ldifferent: // bytes in r7 and r8 differ + sub r3,r7,r8 // compute return value + blr + diff --git a/ppc/string/strcat.s b/ppc/string/strcat.s new file mode 100644 index 0000000..469ae20 --- /dev/null +++ b/ppc/string/strcat.s @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// *************** +// * S T R C A T * +// *************** +// +// char* strcat(const char *dst, const char *src); +// +// 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 "lwz" that crosses a page boundary, +// and never store a byte we don't have to. +// +// 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 EXT(strcat) + + .align 5 +LEXT(strcat) // char* strcat(const char *s, const char *append); + andi. r0,r3,3 // is dst aligned? + dcbtst 0,r3 // touch in dst + lis r6,hi16(0xFEFEFEFF) // start to load magic constants + lis r7,hi16(0x80808080) + dcbt 0,r4 // touch in source + ori r6,r6,lo16(0xFEFEFEFF) + ori r7,r7,lo16(0x80808080) + mr r9,r3 // use r9 for dest ptr (must return r3 intact) + beq Lword0loop // dest is aligned + subfic r0,r0,4 // r0 <- #bytes to word align dest + mtctr r0 + +// Loop over bytes looking for 0-byte marking end of dest. +// r4 = source ptr (unalaigned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = byte count + +Lbyte0loop: + lbz r8,0(r9) // r8 <- next dest byte + addi r9,r9,1 + cmpwi r8,0 // test for 0 + bdnzf eq,Lbyte0loop // loop until (ctr==0) | (r8==0) + + bne Lword0loop // enter word loop if we haven't found the 0-byte + subi r9,r9,1 // point to 0-byte + b L0found // start to append the source + +// Loop over words looking for 0-byte marking end of dest. +// r4 = source ptr (unalaigned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (word aligned) + + .align 5 // align inner loops for speed +Lword0loop: + lwz r8,0(r9) // r8 <- next dest word + addi r9,r9,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + beq Lword0loop // loop until 0 found + + slwi r0,r8,7 // move 0x01 bits (false hits) into 0x80 position + subi r9,r9,4 // back r9 up to beginning of word + andc r11,r11,r0 // mask out false hits + cntlzw r0,r11 // find 0 byte (r0 = 0, 8, 16, or 24) + srwi r0,r0,3 // now r0 = 0, 1, 2, or 3 + add r9,r9,r0 // now r9 points to the 0-byte in dest + +// End of dest found, so we can start appending source. +// We align the _source_, which allows us to avoid all worries about +// spurious page faults. Doing so is faster than aligning the dest. +// r4 = source ptr (unaligned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = ptr to 0-byte (unaligned) + +L0found: + andi. r0,r4,3 // is source aligned? + beq LwordloopEnter // skip if so + subfic r0,r0,4 // not aligned, get #bytes to align r4 + mtctr r0 // set up loop + +// Loop over bytes. +// r4 = source ptr (unaligned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = byte count + +Lbyteloop: + lbz r8,0(r4) // r8 <- next source byte + addi r4,r4,1 + cmpwi r8,0 // 0 ? + stb r8,0(r9) // pack into dest + addi r9,r9,1 + bdnzf eq,Lbyteloop // loop until (ctr==0) | (r8==0) + + bne LwordloopEnter // 0-byte not found, so enter word loop + blr // 0-byte found, done + +// Word loop: move a word at a time until 0-byte found. +// r4 = source ptr (word aligned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + + .align 5 // align inner loop, which is 8 words ling +Lwordloop: + stw r8,0(r9) // pack word into destination + addi r9,r9,4 +LwordloopEnter: + lwz r8,0(r4) // r8 <- next 4 source bytes + addi r4,r4,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r0,r10,r12 // r0 <- nonzero iff word has a 0-byte + beq Lwordloop // loop if ctr!=0 and cr0_eq + +// Found a 0-byte. Store last word up to and including the 0, a byte at a time. +// r8 = last word, known to have a 0-byte +// r9 = dest ptr + +Lstorelastbytes: + srwi. r0,r8,24 // right justify next byte and test for 0 + slwi r8,r8,8 // shift next byte into position + stb r0,0(r9) // pack into dest + addi r9,r9,1 + bne Lstorelastbytes // loop until 0 stored + + blr + diff --git a/ppc/string/strcmp.s b/ppc/string/strcmp.s new file mode 100644 index 0000000..7cac4da --- /dev/null +++ b/ppc/string/strcmp.s @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// *************** +// * S T R C M P * +// *************** +// +// int strcmp(const char *s1, const char *s2); +// +// We optimize the compare by doing it word parallel. This introduces +// a complication: if we blindly did word loads from both sides until +// finding a difference (or 0), we might get a spurious page fault by +// reading bytes past the difference. To avoid this, we never do a "lwz" +// that crosses a page boundary. +// +// 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 EXT(strcmp) + + .align 5 +LEXT(strcmp) // int strcmp(const char *s1, const char *s2); + andi. r0,r3,3 // is LHS aligned? + dcbt 0,r3 // touch in LHS + lis r5,hi16(0xFEFEFEFF) // start to load magic constants + lis r6,hi16(0x80808080) + dcbt 0,r4 // touch in RHS + ori r5,r5,lo16(0xFEFEFEFF) + ori r6,r6,lo16(0x80808080) + subi r3,r3,4 // we use "lwzu" in the inner loops + subi r4,r4,4 + beq Laligned // LHS is aligned + subfic r0,r0,4 // r0 <- #bytes to word align LHS + mtctr r0 + +// Loop over bytes. + +Lbyteloop: + lbz r7,4(r3) // r7 <- next LHS byte + addi r3,r3,1 + lbz r8,4(r4) // r8 <- next RHS byte + addi r4,r4,1 + cntlzw r9,r7 // is r7 zero? + sub r0,r7,r8 // different? + srwi r9,r9,5 // r9 <- (r7==0) ? 1 : 0 + or. r9,r9,r0 // r9 is nonzero if either different or 0 + bdnzt eq,Lbyteloop // loop until different, 0, or buf end + + bne Ldone // done if different or 0 + +// LHS is word aligned. If RHS also is, we need not worry about page +// crossing. Otherwise, we must stop the word loop before page is crossed. + +Laligned: + andi. r0,r4,3 // is RHS now word aligned too? + addi r9,r4,4 // restore true address of next RHS byte + rlwinm r9,r9,0,0xFFF // get RHS offset in page + beq Lalignedloop // RHS word aligned, use simple loop + subfic r9,r9,4096 // get #bytes left in RHS page + srwi. r0,r9,2 // get #words left in RHS page + mtctr r0 // set up loop count + bne++ Lunalignedloop // at least one word left in RHS page + li r0,4 // must check 4 bytes, a byte at a time... + mtctr r0 // ...in order to keep LHS word aligned + b Lbyteloop // go cross RHS page + +// Unaligned inner loop: compare a word at a time, until one of three conditions: +// - a difference is found +// - a zero byte is found +// - end of RHS page (we dare not touch next page until we must) +// At this point, registers are as follows: +// r3 = LHS ptr - 4 (word aligned) +// r4 = RHS ptr - 4 (not aligned) +// r5 = 0xFEFEFEFF +// r6 = 0x80808080 +// ctr = whole words left in RHS page + + .align 5 // align inner loop, which is 8 words long +Lunalignedloop: + lwzu r7,4(r3) // r7 <- next 4 LHS bytes + lwzu r8,4(r4) // r8 <- next 4 RHS bytes + add r10,r7,r5 // r10 <- LHS + 0xFEFEFEFF + andc r12,r6,r7 // r12 <- ~LHS & 0x80808080 + xor r11,r7,r8 // r11 <- compare the words + and r0,r10,r12 // r0 <- nonzero iff LHS has a 0-byte + or. r12,r0,r11 // combine difference and 0-test vectors + bdnzt eq,Lunalignedloop // loop if ctr!=0 and cr0_eq + + bne++ Ldifferent // done if we found a 0 or difference + li r0,4 // must check 4 bytes, a byte at a time... + mtctr r0 // ...in order to keep LHS word aligned + b Lbyteloop // cross RHS page, then resume word loop + +// Aligned inner loop: compare a word at a time, until one of two conditions: +// - a difference is found +// - a zero byte is found +// At this point, registers are as follows: +// r3 = LHS ptr - 4 (word aligned) +// r4 = RHS ptr - 4 (word aligned) +// r5 = 0xFEFEFEFF +// r6 = 0x80808080 + + .align 5 // align inner loop, which is 8 words ling +Lalignedloop: + lwzu r7,4(r3) // r7 <- next 4 LHS bytes + lwzu r8,4(r4) // r8 <- next 4 RHS bytes + add r10,r7,r5 // r10 <- LHS + 0xFEFEFEFF + andc r12,r6,r7 // r12 <- ~LHS & 0x80808080 + xor r11,r7,r8 // r11 <- compare the words + and r0,r10,r12 // r0 <- nonzero iff LHS has a 0-byte + or. r12,r0,r11 // combine difference and 0-test vectors + beq Lalignedloop // loop if neither found + +// Found differing bytes and/or a 0-byte. Determine which comes first, and +// subtract the bytes to compute the return value. We also need to mask out the +// false hits in the 0-byte test, which consist of 0x01 bytes that preceed +// the 0-byte. + +Ldifferent: // r0 == 0-test vector (with 0x01 false hits) + slwi r9,r7,7 // move 0x01 bits in LHS into position 0x80 + andc r0,r0,r9 // mask out the false 0-hits from 0x01 bytes + or r11,r11,r0 // recompute difference vector + cntlzw r9,r11 // find 1st difference (r9 = 0..31) + rlwinm r9,r9,0,0x18 // byte align bit offset (now, r9 = 0,8,16, or 24) + addi r9,r9,8 // now, r9 = 8, 16, 24, or 32 + rlwnm r5,r7,r9,24,31 // right justify differing bytes and mask off rest + rlwnm r6,r8,r9,24,31 + sub r3,r5,r6 // compute difference (0, +, or -) + blr + +Ldone: // r0 = return value + mr r3,r0 // return in r3 + blr + diff --git a/ppc/string/strcpy.s b/ppc/string/strcpy.s new file mode 100644 index 0000000..9d74580 --- /dev/null +++ b/ppc/string/strcpy.s @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// *************** +// * S T R C P Y * +// *************** +// +// char* strcpy(const char *dst, const char *src); +// +// 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 "lwz" that crosses a page boundary, +// and never store a byte we don't have to. +// +// 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. +// +// We align the _source_, which allows us to avoid all worries about +// spurious page faults. Doing so is faster than aligning the dest. + + .text + .globl EXT(strcpy) + + .align 5 +LEXT(strcpy) // char* strcpy(const char *dst, const char *src); + andi. r0,r4,3 // is source aligned? + dcbt 0,r4 // touch in source + lis r6,hi16(0xFEFEFEFF) // start to load magic constants + lis r7,hi16(0x80808080) + dcbtst 0,r3 // touch in dst + ori r6,r6,lo16(0xFEFEFEFF) + ori r7,r7,lo16(0x80808080) + mr r9,r3 // use r9 for dest ptr (must return r3 intact) + beq LwordloopEnter // source is aligned + subfic r0,r0,4 // r0 <- #bytes to word align source + mtctr r0 + +// Loop over bytes. +// r4 = source ptr (unaligned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = byte count + +Lbyteloop: + lbz r8,0(r4) // r8 <- next source byte + addi r4,r4,1 + cmpwi r8,0 // 0 ? + stb r8,0(r9) // pack into dest + addi r9,r9,1 + bdnzf eq,Lbyteloop // loop until (ctr==0) | (r8==0) + + bne LwordloopEnter // 0-byte not found, so enter word loop + blr // 0-byte found, done + +// Word loop: move a word at a time until 0-byte found. +// r4 = source ptr (word aligned) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + + .align 5 // align inner loop, which is 8 words ling +Lwordloop: + stw r8,0(r9) // pack word into destination + addi r9,r9,4 +LwordloopEnter: + lwz r8,0(r4) // r8 <- next 4 source bytes + addi r4,r4,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r0,r10,r12 // r0 <- nonzero iff word has a 0-byte + beq Lwordloop // loop if ctr!=0 and cr0_eq + +// Found a 0-byte. Store last word up to and including the 0, a byte at a time. +// r8 = last word, known to have a 0-byte +// r9 = dest ptr + +Lstorelastbytes: + srwi. r0,r8,24 // right justify next byte and test for 0 + slwi r8,r8,8 // shift next byte into position + stb r0,0(r9) // pack into dest + addi r9,r9,1 + bne Lstorelastbytes // loop until 0 stored + + blr + diff --git a/ppc/string/strlcat.s b/ppc/string/strlcat.s new file mode 100644 index 0000000..4a6622f --- /dev/null +++ b/ppc/string/strlcat.s @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// ***************** +// * S T R L C A T * +// ***************** +// +// size_t strlcat(char *dst, const char *src, size_t count); +// +// 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. +// We are allowed to touch the "count" bytes starting at "dst", but +// when appending the "src", we must not do a "lwz" that crosses a page +// boundary, or store past "count". +// +// 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. +// +// Note that "count" is the total buffer length, including the length +// of the "dst" string. This is different than strncat(). + + .text + .globl EXT(strlcat) + + .align 5 +LEXT(strlcat) + srwi. r0,r5,2 // get #words to scan + dcbtst 0,r3 // touch in dst + lis r6,hi16(0xFEFEFEFF) // start to load magic constants + lis r7,hi16(0x80808080) + dcbt 0,r4 // touch in source + ori r6,r6,lo16(0xFEFEFEFF) + ori r7,r7,lo16(0x80808080) + mr r9,r3 // use r9 for dest ptr (r3 remembers dst start) + beq-- L0bytes // buffer length <4 + mtctr r0 // set up loop + b L0words // enter word loop + +// Loop over words looking for 0. +// r3 = original start of buffer +// r4 = source ptr (unaligned) +// r5 = original buffer size +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = #words remaining in buffer + + .align 5 // align inner loops for speed +L0words: + lwz r8,0(r9) // r8 <- next dest word + addi r9,r9,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + bdnzt eq,L0words // loop until 0 found or buffer end + + beq-- L0bytes // skip if 0 not found + + slwi r0,r8,7 // move 0x01 bits (false hits) into 0x80 position + subi r9,r9,4 // back up r9 to the start of the word + andc r11,r11,r0 // mask out false hits + cntlzw r0,r11 // find 0 byte (r0 = 0, 8, 16, or 24) + srwi r0,r0,3 // now r0 = 0, 1, 2, or 3 + add r9,r9,r0 // now r9 points to the 0-byte in dest + b L0found // start to append source + +// Loop over bytes looking for 0. +// r3 = original start of buffer +// r4 = source ptr (unaligned) +// r5 = original buffer size +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +L0bytes: + andi. r0,r5,3 // get #bytes remaining in buffer + mtctr r0 // set up byte loop + beq-- L0notfound // skip if 0 not found in buffer (error) +L0byteloop: + lbz r8,0(r9) // r8 <- next dest byte + addi r9,r9,1 + cmpwi r8,0 // 0 ? + bdnzf eq,L0byteloop // loop until 0 found or buffer end + + bne-- L0notfound // skip if 0 not found (error) + subi r9,r9,1 // back up, so r9 points to the 0 + +// End of dest found, so we can start appending source. First, align the source, +// in order to avoid spurious page faults. +// r3 = original start of buffer +// r4 = original source ptr (unaligned) +// r5 = original buffer size +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = ptr to 0-byte in dest (unaligned) + +L0found: + andi. r0,r4,3 // is source aligned? + add r5,r5,r3 // get ptr to end of buffer + sub r5,r5,r9 // get #bytes remaining in buffer, counting the 0 (r5>0) + beq Laligned // skip if source already word aligned + subfic r0,r0,4 // not aligned, get #bytes to align r4 + b Lbyteloop1 // r5!=0, so skip check + +// Copy min(r0,r5) bytes, until 0-byte. +// r0 = #bytes we propose to copy (NOTE: must be >0) +// r4 = source ptr (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Lbyteloop: + cmpwi r5,0 // buffer empty? (note: unsigned) + beq-- Loverrun // buffer filled before end of source reached +Lbyteloop1: // entry when we know r5!=0 + lbz r8,0(r4) // r8 <- next source byte + subic. r0,r0,1 // decrement count of bytes to move + addi r4,r4,1 + subi r5,r5,1 // decrement buffer length remaining + stb r8,0(r9) // pack into dest + cmpwi cr1,r8,0 // 0-byte? + addi r9,r9,1 + beq cr1,L0stored // byte was 0, so done + bne Lbyteloop // r0!=0, source not yet aligned + +// Source is word aligned. Loop over words until 0-byte found or end +// of buffer. +// r3 = original start of buffer +// r4 = source ptr (word aligned) +// r5 = length remaining in buffer +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Laligned: + srwi. r8,r5,2 // get #words in buffer + addi r0,r5,1 // if no words... + beq-- Lbyteloop // ...copy to end of buffer + mtctr r8 // set up word loop count + rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes + b LwordloopEnter + +// Inner loop: move a word at a time, until one of two conditions: +// - a zero byte is found +// - end of buffer +// At this point, registers are as follows: +// r3 = original start of buffer +// r4 = source ptr (word aligned) +// r5 = bytes leftover in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = whole words left in buffer + + .align 5 // align inner loop, which is 8 words long +Lwordloop: + stw r8,0(r9) // pack word into destination + addi r9,r9,4 +LwordloopEnter: + lwz r8,0(r4) // r8 <- next 4 source bytes + addi r4,r4,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq + + beq-- Lleftovers // skip if no 0-byte found, copy leftovers + +// Found a 0-byte. Store last word up to and including the 0, a byte at a time. +// r3 = original start of buffer +// r8 = last word, known to have a 0-byte +// r9 = dest ptr (one past 0) + +Lstorelastbytes: + srwi. r0,r8,24 // right justify next byte and test for 0 + slwi r8,r8,8 // shift next byte into position + stb r0,0(r9) // pack into dest + addi r9,r9,1 + bne Lstorelastbytes // loop until 0 stored + +// Append op successful, O stored into buffer. Return total length. +// r3 = original start of buffer +// r9 = dest ptr (one past 0) + +L0stored: + sub r3,r9,r3 // get (length+1) of string in buffer + subi r3,r3,1 // return length + blr + +// 0-byte not found in aligned source words. There are up to 3 leftover source +// bytes, hopefully the 0-byte is among them. +// r4 = source ptr (word aligned) +// r5 = leftover bytes in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r8 = last full word of source +// r9 = dest ptr (unaligned) + +Lleftovers: + stw r8,0(r9) // store last word + addi r9,r9,4 + addi r0,r5,1 // make sure r5 terminates byte loop (not r0) + b Lbyteloop + +// Buffer filled during append without finding the end of source. Overwrite the +// last byte in buffer with a 0, and compute how long the concatenated string would +// have been, if the buffer had been large enough. +// r3 = original start of buffer +// r4 = source ptr (1st byte not copied into buffer) +// r9 = dest ptr (one past end of buffer) + +Loverrun: + sub. r3,r9,r3 // compute #bytes stored in buffer + li r0,0 // get a 0 + beq-- Lskip // buffer was 0-length + stb r0,-1(r9) // jam in delimiting 0 + +// Buffer full, check to see how much longer source is. We don't optimize this, +// since overruns are an error. + +Lskip: + lbz r8,0(r4) // get next source byte + addi r4,r4,1 + addi r3,r3,1 // increment length of "ideal" string + cmpwi r8,0 // 0? + bne Lskip + + subi r3,r3,1 // don't count 0 in length + blr // return length of string we "wanted" to create + +// 0 not found in buffer (append not yet begun.) We don't store a delimiting 0, +// but do compute how long the concatenated string would have been, assuming the length +// of "dst" is the length of the buffer. +// r3 = original start of buffer +// r4 = original source ptr +// r9 = dest ptr (one past end of buffer) + +L0notfound: + sub r3,r9,r3 // compute #bytes in buffer + b Lskip // add strlen(source) to r3 + diff --git a/ppc/string/strlcpy.s b/ppc/string/strlcpy.s new file mode 100644 index 0000000..1707da6 --- /dev/null +++ b/ppc/string/strlcpy.s @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// ***************** +// * 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 "lwz" 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 EXT(strlcpy) + + .align 5 +LEXT(strlcpy) + andi. r0,r4,3 // is source aligned? + dcbt 0,r4 // touch in source + lis r6,hi16(0xFEFEFEFF) // start to load magic constants + lis r7,hi16(0x80808080) + dcbtst 0,r3 // touch in dst + ori r6,r6,lo16(0xFEFEFEFF) + ori r7,r7,lo16(0x80808080) + mr r9,r3 // use r9 for dest ptr (r3 remembers dst start) + beq Laligned // source is aligned + subfic r0,r0,4 // r0 <- #bytes to word align source + +// Copy min(r0,r5) bytes, until 0-byte found. +// r0 = #bytes we propose to copy (NOTE: must be >0) +// r4 = source ptr (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Lbyteloop: + cmpwi r5,0 // buffer empty? + beq-- L0notfound // buffer full but 0 not found + lbz r8,0(r4) // r8 <- next source byte + subic. r0,r0,1 // decrement count of bytes to move + addi r4,r4,1 + subi r5,r5,1 // decrement buffer length remaining + stb r8,0(r9) // pack into dest + cmpwi cr1,r8,0 // 0-byte? + addi r9,r9,1 + beq cr1,L0found // byte was 0 + bne Lbyteloop // r0!=0, source not yet aligned + +// Source is word aligned. Loop over words until end of buffer. We align +// the source, rather than the dest, to avoid getting spurious page faults. +// r4 = source ptr (word aligned) +// r5 = length remaining in buffer +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Laligned: + srwi. r8,r5,2 // get #words in buffer + addi r0,r5,1 // if no words, compare rest of buffer + beq Lbyteloop // r8==0, no words + mtctr r8 // set up word loop count + rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes + b LwordloopEnter + +// Move a word at a time, until one of two conditions: +// - a zero byte is found +// - end of buffer +// At this point, registers are as follows: +// r4 = source ptr (word aligned) +// r5 = leftover bytes in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = whole words left in buffer + + .align 5 // align inner loop, which is 8 words long +Lwordloop: + stw r8,0(r9) // pack word into destination + addi r9,r9,4 +LwordloopEnter: + lwz r8,0(r4) // r8 <- next 4 source bytes + addi r4,r4,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq + + beq Lleftovers // 0-byte not found in aligned words + +// Found a 0-byte. Store last word up to and including the 0, a byte at a time. +// r8 = last word, known to have a 0-byte +// r9 = dest ptr + +Lstorelastbytes: + srwi. r0,r8,24 // right justify next byte and test for 0 + slwi r8,r8,8 // shift next byte into position + stb r0,0(r9) // pack into dest + addi r9,r9,1 + bne Lstorelastbytes // loop until 0 stored + +L0found: + sub r3,r9,r3 // get #bytes stored, including 0 + subi r3,r3,1 // don't count the 0 + blr // return strlen(src) + +// 0-byte not found in aligned source words. There are up to 3 leftover source +// bytes, hopefully the 0-byte is among them. +// r4 = source ptr (word aligned) +// r5 = leftover bytes in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r8 = last full word of source +// r9 = dest ptr (unaligned) + +Lleftovers: + stw r8,0(r9) // store last word + addi r9,r9,4 + addi r0,r5,1 // make sure r5 terminate byte loop (not r0) + b Lbyteloop + +// Buffer full but 0-byte not found. Stuff a 0 into last byte of buffer. +// r3 = start of buffer +// r4 = ptr to next byte in source +// r9 = ptr to first byte past end of buffer + +L0notfound: + sub. r3,r9,r3 // get #bytes stored, ie original buffer length + beq Lfind0 // skip if buffer 0-length + li r0,0 // get a 0 + stb r0,-1(r9) // always store 0-byte unless buffer was 0-length + +// Keep searching for 0-byte ending source, so we can return strlen(source). +// Not optimized, since this is an error condition. +// r3 = number of bytes already copied +// r4 = ptr to next byte in source + +Lfind0: + lbz r0,0(r4) // get next byte + addi r4,r4,1 + addi r3,r3,1 // increment strlen + cmpwi r0,0 + bne Lfind0 // loop if not 0 + + subi r3,r3,1 // don't count the 0-byte + blr // return strlen(source) diff --git a/ppc/gen/strlen.s b/ppc/string/strlen.s similarity index 99% rename from ppc/gen/strlen.s rename to ppc/string/strlen.s index 77a9769..806e00e 100644 --- a/ppc/gen/strlen.s +++ b/ppc/string/strlen.s @@ -22,6 +22,10 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#define ASSEMBLER +#include +#undef ASSEMBLER + ; ; ; Strlen, optimized for PPC. The routine we use is 2-3x faster @@ -40,7 +44,6 @@ ; with one exception: 0x01 bytes preceeding the first zero are also ; mapped to 0x80. ; -#include ; ; int strlen(ptr) ; diff --git a/ppc/string/strncat.s b/ppc/string/strncat.s new file mode 100644 index 0000000..91b114e --- /dev/null +++ b/ppc/string/strncat.s @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// ***************** +// * S T R N C A T * +// ***************** +// +// char* strncat(char *dst, const char *src, size_t count); +// +// 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 "lwz" that crosses a page boundary, +// or store extra 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. +// +// Note that "count" refers to the max number of bytes to _append_. +// There is no limit to the number of bytes we will scan looking for +// the end of the "dst" string. + + .text + .globl EXT(strncat) + + .align 5 +LEXT(strncat) + andi. r0,r3,3 // is dst aligned? + dcbtst 0,r3 // touch in dst + lis r6,hi16(0xFEFEFEFF) // start to load magic constants + lis r7,hi16(0x80808080) + dcbt 0,r4 // touch in source + ori r6,r6,lo16(0xFEFEFEFF) + ori r7,r7,lo16(0x80808080) + mr r9,r3 // use r9 for dest ptr (must return r3 intact) + beq Lword0loop // dest is aligned + subfic r0,r0,4 // r0 <- #bytes to word align dest + mtctr r0 // set up byte loop + +// Loop over bytes looking for 0-byte marking end of dest, until dest is +// word aligned. +// r4 = source ptr (unaligned) +// r5 = count (unchanged so far) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = byte count + +Lbyte0loop: + lbz r8,0(r9) // r8 <- next dest byte + addi r9,r9,1 + cmpwi r8,0 // test for 0 + bdnzf eq,Lbyte0loop // loop until (ctr==0) | (r8==0) + + bne Lword0loop // haven't found 0, so enter word-aligned loop + andi. r0,r4,3 // is source aligned? + subi r9,r9,1 // point to the 0-byte we just stored + beq Laligned // source is already aligned + subfic r0,r0,4 // r0 <- #bytes to word align source + b Lbyteloop // must align source + +// Loop over words looking for 0-byte marking end of dest. +// r4 = source ptr (unaligned) +// r5 = count (unchanged so far) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (word aligned) + + .align 5 // align inner loops for speed +Lword0loop: + lwz r8,0(r9) // r8 <- next dest word + addi r9,r9,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + beq Lword0loop // loop until 0 found + + slwi r10,r8,7 // move 0x01 bits (false hits) into 0x80 position + andi. r0,r4,3 // is source aligned? + andc r11,r11,r10 // mask out false hits + subi r9,r9,4 // back up r9 to the start of the word + cntlzw r10,r11 // find 0 byte (r0 = 0, 8, 16, or 24) + srwi r10,r10,3 // now r10 = 0, 1, 2, or 3 + add r9,r9,r10 // now r9 points to the 0-byte in dest + beq Laligned // skip if source already aligned + subfic r0,r0,4 // r0 <- #bytes to word align source + +// Copy min(r0,r5) bytes, until 0-byte. +// r0 = #bytes we propose to copy (NOTE: must be >0) +// r4 = source ptr (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Lbyteloop: + cmpwi r5,0 // buffer empty? (note: unsigned) + beq-- L0notfound // buffer full but 0 not found + lbz r8,0(r4) // r8 <- next source byte + subic. r0,r0,1 // decrement count of bytes to move + addi r4,r4,1 + subi r5,r5,1 // decrement buffer length remaining + stb r8,0(r9) // pack into dest + cmpwi cr1,r8,0 // 0-byte? + addi r9,r9,1 + beqlr cr1 // byte was 0, so done + bne Lbyteloop // r0!=0, source not yet aligned + +// Source is word aligned. Loop over words until 0-byte found or end +// of buffer. +// r4 = source ptr (word aligned) +// r5 = length remaining in buffer +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Laligned: + srwi. r8,r5,2 // get #words in buffer + addi r0,r5,1 // if no words, copy rest of buffer + beq-- Lbyteloop // fewer than 4 bytes in buffer + mtctr r8 // set up word loop count + rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes + b LwordloopEnter + +// Inner loop: move a word at a time, until one of two conditions: +// - a zero byte is found +// - end of buffer +// At this point, registers are as follows: +// r4 = source ptr (word aligned) +// r5 = bytes leftover in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = whole words left in buffer + + .align 5 // align inner loop, which is 8 words long +Lwordloop: + stw r8,0(r9) // pack word into destination + addi r9,r9,4 +LwordloopEnter: + lwz r8,0(r4) // r8 <- next 4 source bytes + addi r4,r4,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq + + beq-- LcheckLeftovers // skip if 0-byte not found + +// Found a 0-byte. Store last word up to and including the 0, a byte at a time. +// r8 = last word, known to have a 0-byte +// r9 = dest ptr + +Lstorelastbytes: + srwi. r0,r8,24 // right justify next byte and test for 0 + slwi r8,r8,8 // shift next byte into position + stb r0,0(r9) // pack into dest + addi r9,r9,1 + bne Lstorelastbytes // loop until 0 stored + + blr + +// 0-byte not found while appending words to source. There might be up to +// 3 "leftover" bytes to append, hopefully the 0-byte is in there. +// r4 = source ptr (past word in r8) +// r5 = bytes leftover in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r8 = last word of source, with no 0-byte +// r9 = dest ptr (unaligned) + +LcheckLeftovers: + stw r8,0(r9) // store last whole word of source + addi r9,r9,4 + addi r0,r5,1 // let r5 (not r0) terminate byte loop + b Lbyteloop // append last few bytes + +// 0-byte not found in source. We append a 0 anyway, even though it will +// be past the end of the buffer. That's the way it's defined. +// r9 = dest ptr + +L0notfound: + li r0,0 + stb r0,0(r9) // add a 0, past end of buffer + blr + diff --git a/ppc/string/strncmp.s b/ppc/string/strncmp.s new file mode 100644 index 0000000..6fee8ce --- /dev/null +++ b/ppc/string/strncmp.s @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER // we need the defs for cr7_eq etc +#include +#undef ASSEMBLER + +// ***************** +// * S T R N C M P * +// ***************** +// +// int strncmp(const char *s1, const char *s2, size_t len); +// +// We optimize the compare by doing it word parallel. This introduces +// a complication: if we blindly did word loads from both sides until +// finding a difference (or 0), we might get a spurious page fault by +// reading bytes past the difference. To avoid this, we never do a "lwz" +// that crosses a page boundary. +// +// 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 EXT(strncmp) + + .align 5 +LEXT(strncmp) // int strncmp(const char *s1,const char *s2,size_t len); + cmplwi cr1,r5,8 // is buffer too short to bother with word compares? + andi. r0,r3,3 // is LHS aligned? + dcbt 0,r3 // touch in LHS + subi r3,r3,4 // we use "lwzu" in the word inner loop + subi r4,r4,4 + blt cr1,Lshort // short buffer, just compare a byte at a time + lis r2,hi16(0xFEFEFEFF) // start to load magic constants + lis r6,hi16(0x80808080) + ori r2,r2,lo16(0xFEFEFEFF) + ori r6,r6,lo16(0x80808080) + beq Laligned // LHS is aligned + subfic r0,r0,4 // r0 <- #bytes to word align LHS + mtctr r0 // set up for byte loop + sub r5,r5,r0 // adjust length + b Lbyteloop + +// Handle short operands or end-of-buffer. +// r3 = LHS ptr - 4 (unaligned) +// r4 = RHS ptr - 4 (unaligned) +// r5 = length remaining in buffer (0..7) +// cr1 = blt set + +Lshort: + cmpwi r5,0 // buffer null? + mtctr r5 // assume not null, set up for loop + bne Lbyteloop // buffer not null + li r3,0 // if buffer null, say "equal" + blr + +// We're at a RHS page boundary. Compare 4 bytes in order to cross the page +// but still keep the LHS ptr word-aligned. +// r2 = 0xFEFEFEFF +// r3 = LHS ptr - 4 (aligned) +// r4 = RHS ptr - 4 (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0x80808080 + +Lcrosspage: + cmplwi cr1,r5,8 // not enough left in buffer for word compares? + li r0,4 // get #bytes to cross RHS page + blt cr1,Lshort // buffer is about to end + mtctr r0 // set up to compare 4 bytes + sub r5,r5,r0 // adjust length + b Lbyteloop + +// Compare bytes, until 0-byte or difference found. +// r2 = 0xFEFEFEFF (if cr1 bge) +// r3 = LHS ptr - 4 (unaligned) +// r4 = RHS ptr - 4 (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0x80808080 (if cr1 bge) +// cr1 = blt if this is end of buffer + + .align 5 // align inner loop, which is 8 words long +Lbyteloop: + lbz r7,4(r3) // next LHS byte + addi r3,r3,1 + lbz r8,4(r4) // next RHS byte + addi r4,r4,1 + cmpwi cr0,r7,0 // zero? + cmpw cr7,r7,r8 // equal? + crandc cr0_eq,cr7_eq,cr0_eq// set cr0_eq if equal and not 0 + bdnzt eq,Lbyteloop // loop until different, 0, or (ctr==0) + + bne Ldifferent // done if bytes differ or are 0 + blt cr1,Ldifferent // done if buffer end (ie, if r5==0) + +// LHS is now word aligned. Loop over words until end of RHS page or buffer. +// When we get to the end of the page, we compare 4 bytes, so that we keep +// the LHS word aligned. +// r2 = 0xFEFEFEFF +// r3 = LHS ptr - 4 (aligned) +// r4 = RHS ptr - 4 (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0x80808080 + +Laligned: + addi r9,r4,4 // restore true address of next RHS byte + rlwinm r9,r9,0,0xFFF // get RHS offset in page + subfic r0,r9,4096 // get #bytes left in RHS page + subfc r7,r0,r5 // *** + subfe r8,r5,r5 // * r9 <- min(r0,r5), + and r7,r7,r8 // * using algorithm in Compiler Writer's Guide + add r9,r0,r7 // *** + srwi. r8,r9,2 // get #words we can compare + beq-- Lcrosspage // no words so advance to next RHS page + slwi r9,r8,2 // convert #words to #bytes + mtctr r8 // set up loop count + sub r5,r5,r9 // decrement length remaining + b Lwordloop + +// Inner loop: compare a word at a time, until one of three conditions: +// - a difference is found +// - a zero byte is found +// - end of count (ie, end of buffer or RHS page, whichever is first) +// At this point, registers are as follows: +// r2 = 0xFEFEFEFF +// r3 = LHS ptr - 4 (aligned) +// r4 = RHS ptr - 4 (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0x80808080 +// ctr = count of words until end of buffer or RHS page + + .align 5 // align inner loop, which is 8 words long +Lwordloop: + lwzu r7,4(r3) // r7 <- next 4 LHS bytes + lwzu r8,4(r4) // r8 <- next 4 RHS bytes + add r10,r7,r2 // r10 <- LHS + 0xFEFEFEFF + andc r12,r6,r7 // r12 <- ~LHS & 0x80808080 + xor r11,r7,r8 // r11 <- compare the words + and r9,r10,r12 // r9 <- nonzero iff LHS has a 0-byte + or. r12,r9,r11 // combine difference and 0-test vectors + bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq + + beq-- Lcrosspage // skip if buffer or page end reached + +// Found differing bytes and/or a 0-byte. Determine which comes first, and +// subtract the bytes to compute the return value. We also need to mask out the +// false hits in the 0-byte test, which consist of 0x01 bytes that preceed +// the 0-byte. + + slwi r0,r7,7 // move 0x01 bits in LHS into position 0x80 + andc r9,r9,r0 // mask out the false 0-hits from 0x01 bytes + or r11,r11,r9 // recompute difference vector + cntlzw r0,r11 // find 1st difference (r0 = 0..31) + rlwinm r9,r0,0,0x18 // byte align bit offset (r9 = 0,8,16, or 24) + addi r0,r9,8 // now, r0 = 8, 16, 24, or 32 + rlwnm r7,r7,r0,24,31 // right justify differing bytes and mask off rest + rlwnm r8,r8,r0,24,31 + +Ldifferent: // bytes in r7 and r8 differ or are 0 + sub r3,r7,r8 // compute return value + blr + diff --git a/ppc/string/strncpy.s b/ppc/string/strncpy.s new file mode 100644 index 0000000..c703b66 --- /dev/null +++ b/ppc/string/strncpy.s @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 ASSEMBLER +#include +#undef ASSEMBLER + +// ***************** +// * S T R N C P Y * +// ***************** +// +// char* strncpy(const char *dst, const char *src, size_t len)); +// +// 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 "lwz" 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 EXT(strncpy) + + .align 5 +LEXT(strncpy) + andi. r0,r4,3 // is source aligned? + dcbt 0,r4 // touch in source + lis r6,hi16(0xFEFEFEFF) // start to load magic constants + lis r7,hi16(0x80808080) + dcbtst 0,r3 // touch in dst + ori r6,r6,lo16(0xFEFEFEFF) + ori r7,r7,lo16(0x80808080) + mr r9,r3 // use r9 for dest ptr (must return r3 intact) + add r2,r3,r5 // remember where end of buffer is + beq Laligned // source is aligned + subfic r0,r0,4 // r0 <- #bytes to word align source + +// Copy min(r0,r5) bytes, until 0-byte. +// r0 = #bytes we propose to copy (NOTE: must be >0) +// r2 = ptr to 1st byte not in buffer +// r4 = source ptr (unaligned) +// r5 = length remaining in buffer (may be 0) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Lbyteloop: + cmpwi r5,0 // buffer empty? (note: unsigned) + beqlr-- // buffer full but 0 not found + lbz r8,0(r4) // r8 <- next source byte + subic. r0,r0,1 // decrement count of bytes to move + addi r4,r4,1 + subi r5,r5,1 // decrement buffer length remaining + stb r8,0(r9) // pack into dest + cmpwi cr1,r8,0 // 0-byte? + addi r9,r9,1 + beq cr1,L0found // byte was 0 + bne Lbyteloop // r0!=0, source not yet aligned + +// Source is word aligned. Loop over words until end of buffer. Note that we +// have aligned the source, rather than the dest, in order to avoid spurious +// page faults. +// r2 = ptr to 1st byte not in buffer +// r4 = source ptr (word aligned) +// r5 = length remaining in buffer +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) + +Laligned: + srwi. r8,r5,2 // get #words in buffer + addi r0,r5,1 // if no words, compare rest of buffer + beq-- Lbyteloop // r8==0, no words + mtctr r8 // set up word loop count + rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes + b LwordloopEnter + +// Move a word at a time, until one of two conditions: +// - a zero byte is found +// - end of buffer +// At this point, registers are as follows: +// r2 = ptr to 1st byte not in buffer +// r4 = source ptr (word aligned) +// r5 = leftover bytes in buffer (0..3) +// r6 = 0xFEFEFEFF +// r7 = 0x80808080 +// r9 = dest ptr (unaligned) +// ctr = whole words left in buffer + + .align 5 // align inner loop, which is 8 words long +Lwordloop: + stw r8,0(r9) // pack word into destination + addi r9,r9,4 +LwordloopEnter: + lwz r8,0(r4) // r8 <- next 4 source bytes + addi r4,r4,4 + add r10,r8,r6 // r10 <- word + 0xFEFEFEFF + andc r12,r7,r8 // r12 <- ~word & 0x80808080 + and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte + bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq + + stw r8,0(r9) // pack in last word + addi r9,r9,4 + addi r0,r5,1 // if no 0-byte found... + beq-- Lbyteloop // ...fill rest of buffer a byte at a time + +// Found a 0-byte, point to following byte with r9. + + slwi r0,r8,7 // move 0x01 false hit bits to 0x80 position + andc r11,r11,r0 // mask out false hits + cntlzw r0,r11 // find the 0-byte (r0 = 0,8,16, or 24) + srwi r0,r0,3 // now r0 = 0, 1, 2, or 3 + subfic r0,r0,3 // now r0 = 3, 2, 1, or 0 + sub r9,r9,r0 // now r9 points one past the 0-byte + +// Zero rest of buffer, if any. We don't simply branch to bzero or memset, because +// r3 is set up incorrectly, and there is a fair amt of overhead involved in using them. +// Instead we use a simpler routine, which will nonetheless be faster unless the number +// of bytes to 0 is large and we're on a 64-bit machine. +// r2 = ptr to 1st byte not in buffer +// r9 = ptr to 1st byte to zero + +L0found: + sub r5,r2,r9 // r5 <- #bytes to zero (ie, rest of buffer) + cmplwi r5,32 // how many? + neg r8,r9 // start to compute #bytes to align ptr + li r0,0 // get a 0 + blt Ltail // skip if <32 bytes + andi. r10,r8,31 // get #bytes to 32-byte align + sub r5,r5,r10 // adjust buffer length + srwi r11,r5,5 // get #32-byte chunks + cmpwi cr1,r11,0 // any chunks? + mtctr r11 // set up dcbz loop count + beq 1f // skip if already 32-byte aligned + +// 32-byte align. We just store 32 0s, rather than test and use conditional +// branches. + + stw r0,0(r9) // zero next 32 bytes + stw r0,4(r9) + stw r0,8(r9) + stw r0,12(r9) + stw r0,16(r9) + stw r0,20(r9) + stw r0,24(r9) + stw r0,28(r9) + add r9,r9,r10 // now r9 is 32-byte aligned + beq cr1,Ltail // skip if no 32-byte chunks + b 1f + +// Loop doing 32-byte version of DCBZ instruction. + + .align 4 // align the inner loop +1: + dcbz 0,r9 // zero another 32 bytes + addi r9,r9,32 + bdnz 1b + +// Store trailing bytes. +// r0 = 0 +// r5 = #bytes to store (<32) +// r9 = address + +Ltail: + mtcrf 0x02,r5 // remaining byte count to cr6 and cr7 + mtcrf 0x01,r5 + bf 27,2f // 16-byte chunk? + stw r0,0(r9) + stw r0,4(r9) + stw r0,8(r9) + stw r0,12(r9) + addi r9,r9,16 +2: + bf 28,4f // 8-byte chunk? + stw r0,0(r9) + stw r0,4(r9) + addi r9,r9,8 +4: + bf 29,5f // word? + stw r0,0(r9) + addi r9,r9,4 +5: + bf 30,6f // halfword? + sth r0,0(r9) + addi r9,r9,2 +6: + bflr 31 // byte? + stb r0,0(r9) + blr + + + diff --git a/ppc/sys/ATPgetreq.s b/ppc/sys/ATPgetreq.s index 2f0a83b..e5e9421 100644 --- a/ppc/sys/ATPgetreq.s +++ b/ppc/sys/ATPgetreq.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATPgetreq, 3) - blr diff --git a/ppc/sys/ATPgetrsp.s b/ppc/sys/ATPgetrsp.s index 9437079..d76c6b0 100644 --- a/ppc/sys/ATPgetrsp.s +++ b/ppc/sys/ATPgetrsp.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATPgetrsp, 3) - blr diff --git a/ppc/sys/ATPsndreq.s b/ppc/sys/ATPsndreq.s index e5f7867..fc5e89f 100644 --- a/ppc/sys/ATPsndreq.s +++ b/ppc/sys/ATPsndreq.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATPsndreq, 3) - blr diff --git a/ppc/sys/ATPsndrsp.s b/ppc/sys/ATPsndrsp.s index 5d05206..95b5cc3 100644 --- a/ppc/sys/ATPsndrsp.s +++ b/ppc/sys/ATPsndrsp.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATPsndrsp, 3) - blr diff --git a/ppc/sys/ATgetmsg.s b/ppc/sys/ATgetmsg.s index 1bcf942..c7a9d3c 100644 --- a/ppc/sys/ATgetmsg.s +++ b/ppc/sys/ATgetmsg.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATgetmsg, 3) - blr diff --git a/ppc/sys/ATputmsg.s b/ppc/sys/ATputmsg.s index 0f5f187..bba995d 100644 --- a/ppc/sys/ATputmsg.s +++ b/ppc/sys/ATputmsg.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATputmsg, 3) - blr diff --git a/ppc/sys/ATsocket.s b/ppc/sys/ATsocket.s index 62ef741..b509411 100644 --- a/ppc/sys/ATsocket.s +++ b/ppc/sys/ATsocket.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ATsocket, 3) - blr diff --git a/ppc/sys/Makefile.inc b/ppc/sys/Makefile.inc index 1338cea..6f3b4fb 100644 --- a/ppc/sys/Makefile.inc +++ b/ppc/sys/Makefile.inc @@ -17,6 +17,17 @@ SRCS+= ATPgetreq.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 \ + auditsvc.s \ bind.s \ cerror.s \ chdir.s \ @@ -27,7 +38,6 @@ SRCS+= ATPgetreq.s \ chroot.s \ close.s \ connect.s \ - cthread.s \ dup.s \ dup2.s \ exchangedata.s \ @@ -37,9 +47,11 @@ SRCS+= ATPgetreq.s \ fchmod.s \ fchown.s \ fcntl.s \ + fhopen.s \ flock.s \ fork.s \ fpathconf.s \ + fsctl.s \ fstat.s \ fstatfs.s \ fstatv.s \ @@ -47,6 +59,9 @@ SRCS+= ATPgetreq.s \ ftruncate.s \ futimes.s \ getattrlist.s \ + getaudit.s \ + getaudit_addr.s \ + getauid.s \ getdirentries.s \ getdirentriesattr.s \ getegid.s \ @@ -71,9 +86,14 @@ SRCS+= ATPgetreq.s \ getuid.s \ ioctl.s \ issetugid.s \ + kevent.s \ kill.s \ + kqueue.s \ + kqueue_from_portset_np.s \ + kqueue_portset_np.s \ ktrace.s \ link.s \ + lio_listio.s \ listen.s \ load_shared_file.s \ longjmp.s \ @@ -102,6 +122,7 @@ SRCS+= ATPgetreq.s \ munlockall.s \ munmap.s \ new_system_shared_regions.s \ + nfsclnt.s \ nfssvc.s \ open.s \ pathconf.s \ @@ -131,10 +152,8 @@ SRCS+= ATPgetreq.s \ sem_destroy.s \ sem_getvalue.s \ sem_init.s \ - sem_open.s \ sem_post.s \ sem_trywait.s \ - sem_unlink.s \ sem_wait.s \ semconfig.s \ semctl.s \ @@ -144,6 +163,9 @@ SRCS+= ATPgetreq.s \ sendmsg.s \ sendto.s \ setattrlist.s \ + setaudit.s \ + setaudit_addr.s \ + setauid.s \ setegid.s \ seteuid.s \ setgid.s \ @@ -159,8 +181,6 @@ SRCS+= ATPgetreq.s \ setsockopt.s \ settimeofday.s \ setuid.s \ - shm_open.s \ - shm_unlink.s \ shmat.s \ shmctl.s \ shmdt.s \ @@ -187,7 +207,6 @@ SRCS+= ATPgetreq.s \ undelete.s \ unlink.s \ unmount.s \ - ur_cthread.s \ utimes.s \ vfork.s \ wait4.s \ diff --git a/ppc/sys/SYS.h b/ppc/sys/SYS.h index 357fcdd..50fb22d 100644 --- a/ppc/sys/SYS.h +++ b/ppc/sys/SYS.h @@ -118,7 +118,7 @@ LEAF(_##name) @\ li r0,SYS_##name @\ sc @\ b 1f @\ - b 2f @\ + blr @\ 1: BRANCH_EXTERN(cerror) @\ .text \ 2: nop diff --git a/ppc/sys/_pthread_kill.s b/ppc/sys/_pthread_kill.s index 9d6c94b..5285149 100644 --- a/ppc/sys/_pthread_kill.s +++ b/ppc/sys/_pthread_kill.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(__pthread_kill, 2) - blr diff --git a/ppc/sys/_sysctl.s b/ppc/sys/_sysctl.s index 0962307..cd04a03 100644 --- a/ppc/sys/_sysctl.s +++ b/ppc/sys/_sysctl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(__sysctl, 6) - blr diff --git a/ppc/sys/accept.s b/ppc/sys/accept.s index 13bcc4d..8eaf81a 100644 --- a/ppc/sys/accept.s +++ b/ppc/sys/accept.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(accept, 3) - blr diff --git a/ppc/sys/access.s b/ppc/sys/access.s index 12d789b..7b68e5c 100644 --- a/ppc/sys/access.s +++ b/ppc/sys/access.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(access, 2) - blr diff --git a/ppc/sys/acct.s b/ppc/sys/acct.s index f110336..641f682 100644 --- a/ppc/sys/acct.s +++ b/ppc/sys/acct.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(acct, 1) - blr diff --git a/ppc/sys/add_profil.s b/ppc/sys/add_profil.s index ba86077..de3191c 100644 --- a/ppc/sys/add_profil.s +++ b/ppc/sys/add_profil.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(add_profil, 4) - blr diff --git a/ppc/sys/adjtime.s b/ppc/sys/adjtime.s index 7338f0b..88cfe36 100644 --- a/ppc/sys/adjtime.s +++ b/ppc/sys/adjtime.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(adjtime, 2) - blr diff --git a/ppc/sys/shm_open.s b/ppc/sys/aio_cancel.s similarity index 97% rename from ppc/sys/shm_open.s rename to ppc/sys/aio_cancel.s index 26d65c8..45b2b91 100644 --- a/ppc/sys/shm_open.s +++ b/ppc/sys/aio_cancel.s @@ -24,6 +24,5 @@ */ #include "SYS.h" -SYSCALL(shm_open, 3) - blr +SYSCALL(aio_cancel, 2) diff --git a/ppc/sys/sem_open.s b/ppc/sys/aio_error.s similarity index 97% rename from ppc/sys/sem_open.s rename to ppc/sys/aio_error.s index 9f260d7..1586c01 100644 --- a/ppc/sys/sem_open.s +++ b/ppc/sys/aio_error.s @@ -24,6 +24,5 @@ */ #include "SYS.h" -SYSCALL(sem_open, 4) - blr +SYSCALL(aio_error, 1) diff --git a/ppc/sys/shm_unlink.s b/ppc/sys/aio_fsync.s similarity index 97% rename from ppc/sys/shm_unlink.s rename to ppc/sys/aio_fsync.s index eba4a08..ad5e848 100644 --- a/ppc/sys/shm_unlink.s +++ b/ppc/sys/aio_fsync.s @@ -24,6 +24,5 @@ */ #include "SYS.h" -SYSCALL(shm_unlink, 3) - blr +SYSCALL(aio_fsync, 2) diff --git a/ppc/sys/sem_unlink.s b/ppc/sys/aio_read.s similarity index 97% rename from ppc/sys/sem_unlink.s rename to ppc/sys/aio_read.s index 0281062..e275d1f 100644 --- a/ppc/sys/sem_unlink.s +++ b/ppc/sys/aio_read.s @@ -24,6 +24,5 @@ */ #include "SYS.h" -SYSCALL(sem_unlink, 1) - blr +SYSCALL(aio_read, 1) diff --git a/ppc/sys/aio_return.s b/ppc/sys/aio_return.s new file mode 100644 index 0000000..a82bd0a --- /dev/null +++ b/ppc/sys/aio_return.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..80b8ae3 --- /dev/null +++ b/ppc/sys/aio_suspend.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..7de36b9 --- /dev/null +++ b/ppc/sys/aio_write.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/audit.s b/ppc/sys/audit.s new file mode 100644 index 0000000..9116a19 --- /dev/null +++ b/ppc/sys/audit.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..d3516f9 --- /dev/null +++ b/ppc/sys/auditctl.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..eba3dfe --- /dev/null +++ b/ppc/sys/auditon.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..fc4938c --- /dev/null +++ b/ppc/sys/auditsvc.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/bind.s b/ppc/sys/bind.s index f211bd1..f3a0061 100644 --- a/ppc/sys/bind.s +++ b/ppc/sys/bind.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(bind, 3) - blr diff --git a/ppc/sys/chdir.s b/ppc/sys/chdir.s index 8db4598..283b048 100644 --- a/ppc/sys/chdir.s +++ b/ppc/sys/chdir.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(chdir, 1) - blr diff --git a/ppc/sys/checkuseraccess.s b/ppc/sys/checkuseraccess.s index 74cc341..6ca50f2 100644 --- a/ppc/sys/checkuseraccess.s +++ b/ppc/sys/checkuseraccess.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(checkuseraccess, 0) - blr diff --git a/ppc/sys/chflags.s b/ppc/sys/chflags.s index b31c863..64c2df6 100644 --- a/ppc/sys/chflags.s +++ b/ppc/sys/chflags.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(chflags, 2) - blr diff --git a/ppc/sys/chmod.s b/ppc/sys/chmod.s index 25d3130..22c8b66 100644 --- a/ppc/sys/chmod.s +++ b/ppc/sys/chmod.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(chmod, 2) - blr diff --git a/ppc/sys/chown.s b/ppc/sys/chown.s index d1931c8..073e2e5 100644 --- a/ppc/sys/chown.s +++ b/ppc/sys/chown.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(chown, 3) - blr diff --git a/ppc/sys/chroot.s b/ppc/sys/chroot.s index 2607074..1f8fd40 100644 --- a/ppc/sys/chroot.s +++ b/ppc/sys/chroot.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(chroot, 1) - blr diff --git a/ppc/sys/close.s b/ppc/sys/close.s index 58214ea..6233e25 100644 --- a/ppc/sys/close.s +++ b/ppc/sys/close.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(close, 1) - blr diff --git a/ppc/sys/connect.s b/ppc/sys/connect.s index c794bc6..97d0c71 100644 --- a/ppc/sys/connect.s +++ b/ppc/sys/connect.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(connect, 3) - blr diff --git a/ppc/sys/dup.s b/ppc/sys/dup.s index 9b90f09..cd10ee7 100644 --- a/ppc/sys/dup.s +++ b/ppc/sys/dup.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(dup, 2) - blr diff --git a/ppc/sys/dup2.s b/ppc/sys/dup2.s index 7cef62f..682ab94 100644 --- a/ppc/sys/dup2.s +++ b/ppc/sys/dup2.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(dup2, 2) - blr diff --git a/ppc/sys/exchangedata.s b/ppc/sys/exchangedata.s index 8952ad6..ea64f83 100644 --- a/ppc/sys/exchangedata.s +++ b/ppc/sys/exchangedata.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(exchangedata, 0) - blr diff --git a/ppc/sys/execve.s b/ppc/sys/execve.s index d392366..6acbd68 100644 --- a/ppc/sys/execve.s +++ b/ppc/sys/execve.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(execve, 3) - blr diff --git a/ppc/sys/fchdir.s b/ppc/sys/fchdir.s index 41a6e7d..bf7829a 100644 --- a/ppc/sys/fchdir.s +++ b/ppc/sys/fchdir.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fchdir, 1) - blr diff --git a/ppc/sys/fchflags.s b/ppc/sys/fchflags.s index 2931c2d..1ceb03c 100644 --- a/ppc/sys/fchflags.s +++ b/ppc/sys/fchflags.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(fchflags, 2) - blr diff --git a/ppc/sys/fchmod.s b/ppc/sys/fchmod.s index 41288fd..70e3e41 100644 --- a/ppc/sys/fchmod.s +++ b/ppc/sys/fchmod.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fchmod, 2) - blr diff --git a/ppc/sys/fchown.s b/ppc/sys/fchown.s index 7eae871..b87d806 100644 --- a/ppc/sys/fchown.s +++ b/ppc/sys/fchown.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fchown, 3) - blr diff --git a/ppc/sys/fcntl.s b/ppc/sys/fcntl.s index 631d242..1601e3a 100644 --- a/ppc/sys/fcntl.s +++ b/ppc/sys/fcntl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fcntl, 3) - blr diff --git a/ppc/sys/fhopen.s b/ppc/sys/fhopen.s new file mode 100644 index 0000000..ba404ae --- /dev/null +++ b/ppc/sys/fhopen.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/flock.s b/ppc/sys/flock.s index 61af923..3e035bf 100644 --- a/ppc/sys/flock.s +++ b/ppc/sys/flock.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(flock, 2) - blr diff --git a/ppc/sys/fork.s b/ppc/sys/fork.s index 52b8c3c..06d7633 100644 --- a/ppc/sys/fork.s +++ b/ppc/sys/fork.s @@ -87,7 +87,6 @@ LC3: #endif li r3,0x0 // clear cached pid in child REG_TO_EXTERN(r3,__current_pid) - CALL_EXTERN(_fork_mach_init) CALL_EXTERN(__cthread_fork_child) #if defined(__DYNAMIC__) .cstring diff --git a/ppc/sys/fpathconf.s b/ppc/sys/fpathconf.s index af1fd1b..291069e 100644 --- a/ppc/sys/fpathconf.s +++ b/ppc/sys/fpathconf.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fpathconf, 2) - blr diff --git a/ppc/sys/fsctl.s b/ppc/sys/fsctl.s new file mode 100644 index 0000000..3e0302f --- /dev/null +++ b/ppc/sys/fsctl.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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/fstat.s b/ppc/sys/fstat.s index 45bc066..bd36610 100644 --- a/ppc/sys/fstat.s +++ b/ppc/sys/fstat.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fstat, 2) - blr diff --git a/ppc/sys/fstatfs.s b/ppc/sys/fstatfs.s index 13594f9..b0476f7 100644 --- a/ppc/sys/fstatfs.s +++ b/ppc/sys/fstatfs.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fstatfs, 2) - blr diff --git a/ppc/sys/fstatv.s b/ppc/sys/fstatv.s index 16cd47b..4f6dd04 100644 --- a/ppc/sys/fstatv.s +++ b/ppc/sys/fstatv.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(fstatv, 0) - blr diff --git a/ppc/sys/fsync.s b/ppc/sys/fsync.s index c6f1d48..c673e49 100644 --- a/ppc/sys/fsync.s +++ b/ppc/sys/fsync.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(fsync, 1) - blr diff --git a/ppc/sys/ftruncate.s b/ppc/sys/ftruncate.s index 5deeea8..c9a77d4 100644 --- a/ppc/sys/ftruncate.s +++ b/ppc/sys/ftruncate.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ftruncate, 2) - blr diff --git a/ppc/sys/futimes.s b/ppc/sys/futimes.s index d3f18e2..208726d 100644 --- a/ppc/sys/futimes.s +++ b/ppc/sys/futimes.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(futimes, 2) - blr diff --git a/ppc/sys/getattrlist.s b/ppc/sys/getattrlist.s index f2c2cc7..462adf3 100644 --- a/ppc/sys/getattrlist.s +++ b/ppc/sys/getattrlist.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(getattrlist, 0) - blr diff --git a/ppc/sys/getaudit.s b/ppc/sys/getaudit.s new file mode 100644 index 0000000..40ffe13 --- /dev/null +++ b/ppc/sys/getaudit.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..10ca54b --- /dev/null +++ b/ppc/sys/getaudit_addr.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..2fe23e4 --- /dev/null +++ b/ppc/sys/getauid.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index cb7cf7d..c14ae25 100644 --- a/ppc/sys/getdirentries.s +++ b/ppc/sys/getdirentries.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getdirentries, 4) - blr diff --git a/ppc/sys/getdirentriesattr.s b/ppc/sys/getdirentriesattr.s index b4774d4..c31ee72 100644 --- a/ppc/sys/getdirentriesattr.s +++ b/ppc/sys/getdirentriesattr.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(getdirentriesattr, 0) - blr diff --git a/ppc/sys/getfh.s b/ppc/sys/getfh.s index 6d700fc..3fdf12b 100644 --- a/ppc/sys/getfh.s +++ b/ppc/sys/getfh.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getfh, 2) - blr diff --git a/ppc/sys/getfsstat.s b/ppc/sys/getfsstat.s index 565b33b..fe4a95c 100644 --- a/ppc/sys/getfsstat.s +++ b/ppc/sys/getfsstat.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getfsstat, 3) - blr diff --git a/ppc/sys/getgid.s b/ppc/sys/getgid.s index d9d3c1e..5c36fb8 100644 --- a/ppc/sys/getgid.s +++ b/ppc/sys/getgid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getgid, 0) - blr diff --git a/ppc/sys/getgroups.s b/ppc/sys/getgroups.s index 3db568a..fa977b1 100644 --- a/ppc/sys/getgroups.s +++ b/ppc/sys/getgroups.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getgroups, 2) - blr diff --git a/ppc/sys/getitimer.s b/ppc/sys/getitimer.s index b3db765..84b9bad 100644 --- a/ppc/sys/getitimer.s +++ b/ppc/sys/getitimer.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getitimer, 2) - blr diff --git a/ppc/sys/getpeername.s b/ppc/sys/getpeername.s index 6a45efd..d9180a8 100644 --- a/ppc/sys/getpeername.s +++ b/ppc/sys/getpeername.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getpeername, 3) - blr diff --git a/ppc/sys/getpgid.s b/ppc/sys/getpgid.s index 396830d..716530d 100644 --- a/ppc/sys/getpgid.s +++ b/ppc/sys/getpgid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getpgid, 1) - blr diff --git a/ppc/sys/getpgrp.s b/ppc/sys/getpgrp.s index 5a4f342..0ceb7ec 100644 --- a/ppc/sys/getpgrp.s +++ b/ppc/sys/getpgrp.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getpgrp, 1) - blr diff --git a/ppc/sys/getpriority.s b/ppc/sys/getpriority.s index 44c3041..d8d8644 100644 --- a/ppc/sys/getpriority.s +++ b/ppc/sys/getpriority.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getpriority, 2) - blr diff --git a/ppc/sys/getrlimit.s b/ppc/sys/getrlimit.s index 2378f63..efe4583 100644 --- a/ppc/sys/getrlimit.s +++ b/ppc/sys/getrlimit.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getrlimit, 2) - blr diff --git a/ppc/sys/getrusage.s b/ppc/sys/getrusage.s index b43ac81..d1f3249 100644 --- a/ppc/sys/getrusage.s +++ b/ppc/sys/getrusage.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getrusage, 2) - blr diff --git a/ppc/sys/getsid.s b/ppc/sys/getsid.s index 95e18b1..5885484 100644 --- a/ppc/sys/getsid.s +++ b/ppc/sys/getsid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getsid, 1) - blr diff --git a/ppc/sys/getsockname.s b/ppc/sys/getsockname.s index 9b2c4c3..f368357 100644 --- a/ppc/sys/getsockname.s +++ b/ppc/sys/getsockname.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getsockname, 3) - blr diff --git a/ppc/sys/getsockopt.s b/ppc/sys/getsockopt.s index b68d269..bfdd42f 100644 --- a/ppc/sys/getsockopt.s +++ b/ppc/sys/getsockopt.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getsockopt, 5) - blr diff --git a/ppc/sys/getuid.s b/ppc/sys/getuid.s index ed8fbb0..a0f8af8 100644 --- a/ppc/sys/getuid.s +++ b/ppc/sys/getuid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(getuid, 0) - blr diff --git a/ppc/sys/ioctl.s b/ppc/sys/ioctl.s index 1e2e55b..c24fe7a 100644 --- a/ppc/sys/ioctl.s +++ b/ppc/sys/ioctl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(ioctl, 3) - blr diff --git a/ppc/sys/issetugid.s b/ppc/sys/issetugid.s index 5f6699e..2353adc 100644 --- a/ppc/sys/issetugid.s +++ b/ppc/sys/issetugid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(issetugid, 0) - blr diff --git a/ppc/sys/kevent.s b/ppc/sys/kevent.s new file mode 100644 index 0000000..e770620 --- /dev/null +++ b/ppc/sys/kevent.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index e67cc95..b2dfe42 100644 --- a/ppc/sys/kill.s +++ b/ppc/sys/kill.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(kill, 2) - blr diff --git a/ppc/sys/kqueue.s b/ppc/sys/kqueue.s new file mode 100644 index 0000000..14be6b3 --- /dev/null +++ b/ppc/sys/kqueue.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..fc2ddcc --- /dev/null +++ b/ppc/sys/kqueue_from_portset_np.s @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..ce2c5c4 --- /dev/null +++ b/ppc/sys/kqueue_portset_np.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 85e95fa..ec8b0b5 100644 --- a/ppc/sys/ktrace.s +++ b/ppc/sys/ktrace.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(ktrace, 4) - blr diff --git a/ppc/sys/link.s b/ppc/sys/link.s index a3d1db3..66213fc 100644 --- a/ppc/sys/link.s +++ b/ppc/sys/link.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(link, 2) - blr diff --git a/ppc/sys/lio_listio.s b/ppc/sys/lio_listio.s new file mode 100644 index 0000000..211987b --- /dev/null +++ b/ppc/sys/lio_listio.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 5cd4e34..98bfeee 100644 --- a/ppc/sys/listen.s +++ b/ppc/sys/listen.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(listen, 2) - blr diff --git a/ppc/sys/load_shared_file.s b/ppc/sys/load_shared_file.s index 1b29b55..14e3731 100644 --- a/ppc/sys/load_shared_file.s +++ b/ppc/sys/load_shared_file.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(load_shared_file, 7) - blr diff --git a/ppc/sys/lseek.s b/ppc/sys/lseek.s index 4e68514..073f3da 100644 --- a/ppc/sys/lseek.s +++ b/ppc/sys/lseek.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(lseek, 3) - blr diff --git a/ppc/sys/lstat.s b/ppc/sys/lstat.s index 1e4bf4e..0528b42 100644 --- a/ppc/sys/lstat.s +++ b/ppc/sys/lstat.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(lstat, 2) - blr diff --git a/ppc/sys/lstatv.s b/ppc/sys/lstatv.s index fdd12bf..da5a26e 100644 --- a/ppc/sys/lstatv.s +++ b/ppc/sys/lstatv.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(lstatv, 0) - blr diff --git a/ppc/sys/madvise.s b/ppc/sys/madvise.s index 85d74c8..5232b4b 100644 --- a/ppc/sys/madvise.s +++ b/ppc/sys/madvise.s @@ -27,5 +27,4 @@ #include "SYS.h" SYSCALL(madvise, 3) - blr diff --git a/ppc/sys/mincore.s b/ppc/sys/mincore.s index 9504e7b..f1df7c9 100644 --- a/ppc/sys/mincore.s +++ b/ppc/sys/mincore.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(mincore, 3) - blr diff --git a/ppc/sys/minherit.s b/ppc/sys/minherit.s index 5d06667..1586259 100644 --- a/ppc/sys/minherit.s +++ b/ppc/sys/minherit.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(minherit, 3) - blr diff --git a/ppc/sys/mkcomplex.s b/ppc/sys/mkcomplex.s index ae39c0c..ba5b176 100644 --- a/ppc/sys/mkcomplex.s +++ b/ppc/sys/mkcomplex.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(mkcomplex, 0) - blr diff --git a/ppc/sys/mkdir.s b/ppc/sys/mkdir.s index e9f9b0b..dbbfd00 100644 --- a/ppc/sys/mkdir.s +++ b/ppc/sys/mkdir.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(mkdir, 2) - blr diff --git a/ppc/sys/mkfifo.s b/ppc/sys/mkfifo.s index f84af75..135a6c6 100644 --- a/ppc/sys/mkfifo.s +++ b/ppc/sys/mkfifo.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(mkfifo, 2) - blr diff --git a/ppc/sys/mknod.s b/ppc/sys/mknod.s index 0317502..df6054c 100644 --- a/ppc/sys/mknod.s +++ b/ppc/sys/mknod.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(mknod, 3) - blr diff --git a/ppc/sys/mlock.s b/ppc/sys/mlock.s index 6500247..a4174d7 100644 --- a/ppc/sys/mlock.s +++ b/ppc/sys/mlock.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(mlock, 3) - blr diff --git a/ppc/sys/mlockall.s b/ppc/sys/mlockall.s index 6cb8722..e61774a 100644 --- a/ppc/sys/mlockall.s +++ b/ppc/sys/mlockall.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(mlockall, 3) - blr diff --git a/ppc/sys/mmap.s b/ppc/sys/mmap.s index 39534bc..623dd7a 100644 --- a/ppc/sys/mmap.s +++ b/ppc/sys/mmap.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(mmap, 6) - blr diff --git a/ppc/sys/mount.s b/ppc/sys/mount.s index 558bbe0..61db678 100644 --- a/ppc/sys/mount.s +++ b/ppc/sys/mount.s @@ -28,4 +28,3 @@ #import "SYS.h" SYSCALL(mount, 4) - blr diff --git a/ppc/sys/mprotect.s b/ppc/sys/mprotect.s index b729d33..eab28c3 100644 --- a/ppc/sys/mprotect.s +++ b/ppc/sys/mprotect.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(mprotect, 3) - blr diff --git a/ppc/sys/msgctl.s b/ppc/sys/msgctl.s index 5717d41..86b873f 100644 --- a/ppc/sys/msgctl.s +++ b/ppc/sys/msgctl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(msgctl, 3) - blr diff --git a/ppc/sys/msgget.s b/ppc/sys/msgget.s index dcb4203..b1c91b6 100644 --- a/ppc/sys/msgget.s +++ b/ppc/sys/msgget.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(msgget, 3) - blr diff --git a/ppc/sys/msgrcv.s b/ppc/sys/msgrcv.s index b636f87..411aebf 100644 --- a/ppc/sys/msgrcv.s +++ b/ppc/sys/msgrcv.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(msgrcv, 3) - blr diff --git a/ppc/sys/msgsnd.s b/ppc/sys/msgsnd.s index 0a2ceed..bc5c10e 100644 --- a/ppc/sys/msgsnd.s +++ b/ppc/sys/msgsnd.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(msgsnd, 3) - blr diff --git a/ppc/sys/msgsys.s b/ppc/sys/msgsys.s index 4d52c2b..e2657d4 100644 --- a/ppc/sys/msgsys.s +++ b/ppc/sys/msgsys.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(msgsys, 3) - blr diff --git a/ppc/sys/msync.s b/ppc/sys/msync.s index f6ff54c..8e683c8 100644 --- a/ppc/sys/msync.s +++ b/ppc/sys/msync.s @@ -26,5 +26,4 @@ #include "SYS.h" -SYSCALL(msync, 2) - blr +SYSCALL(msync, 3) diff --git a/ppc/sys/munlock.s b/ppc/sys/munlock.s index 67a3006..1807a27 100644 --- a/ppc/sys/munlock.s +++ b/ppc/sys/munlock.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(munlock, 3) - blr diff --git a/ppc/sys/munlockall.s b/ppc/sys/munlockall.s index 5c787af..8d8d350 100644 --- a/ppc/sys/munlockall.s +++ b/ppc/sys/munlockall.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(munlockall, 3) - blr diff --git a/ppc/sys/munmap.s b/ppc/sys/munmap.s index 1a36ab6..426aa31 100644 --- a/ppc/sys/munmap.s +++ b/ppc/sys/munmap.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(munmap, 2) - blr diff --git a/ppc/sys/new_system_shared_regions.s b/ppc/sys/new_system_shared_regions.s index aa1f6a2..3277bfb 100644 --- a/ppc/sys/new_system_shared_regions.s +++ b/ppc/sys/new_system_shared_regions.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(new_system_shared_regions, 0) - blr diff --git a/ppc/sys/nfsclnt.s b/ppc/sys/nfsclnt.s new file mode 100644 index 0000000..ba7b380 --- /dev/null +++ b/ppc/sys/nfsclnt.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index 7bf25bc..ec06e6b 100644 --- a/ppc/sys/nfssvc.s +++ b/ppc/sys/nfssvc.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(nfssvc, 1) - blr diff --git a/ppc/sys/open.s b/ppc/sys/open.s index 29da672..d19c77c 100644 --- a/ppc/sys/open.s +++ b/ppc/sys/open.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(open, 3) - blr diff --git a/ppc/sys/pathconf.s b/ppc/sys/pathconf.s index 610ae88..69d0509 100644 --- a/ppc/sys/pathconf.s +++ b/ppc/sys/pathconf.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(pathconf, 2) - blr diff --git a/ppc/sys/ppc_gettimeofday.s b/ppc/sys/ppc_gettimeofday.s index 23a4c79..f40757c 100644 --- a/ppc/sys/ppc_gettimeofday.s +++ b/ppc/sys/ppc_gettimeofday.s @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,6 +26,13 @@ #include "SYS.h" +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + +LEAF(___commpage_gettimeofday) + ba _COMM_PAGE_GETTIMEOFDAY + .globl cerror LEAF(___ppc_gettimeofday) li r0,SYS_gettimeofday diff --git a/ppc/sys/pread.s b/ppc/sys/pread.s index 4235566..2fb578e 100644 --- a/ppc/sys/pread.s +++ b/ppc/sys/pread.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(pread, 4) - blr diff --git a/ppc/sys/profil.s b/ppc/sys/profil.s index fbab01c..a5c262c 100644 --- a/ppc/sys/profil.s +++ b/ppc/sys/profil.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(profil, 4) - blr diff --git a/ppc/sys/pthread_sigmask.s b/ppc/sys/pthread_sigmask.s index 63d035c..31303fd 100644 --- a/ppc/sys/pthread_sigmask.s +++ b/ppc/sys/pthread_sigmask.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(pthread_sigmask, 3) - blr diff --git a/ppc/sys/pwrite.s b/ppc/sys/pwrite.s index 0e05543..14f3537 100644 --- a/ppc/sys/pwrite.s +++ b/ppc/sys/pwrite.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(pwrite, 4) - blr diff --git a/ppc/sys/quota.s b/ppc/sys/quota.s index e6790df..43911b5 100644 --- a/ppc/sys/quota.s +++ b/ppc/sys/quota.s @@ -27,5 +27,4 @@ #define SYS_quota 149 SYSCALL(quota, 4) - blr diff --git a/ppc/sys/quotactl.s b/ppc/sys/quotactl.s index 880832c..7903047 100644 --- a/ppc/sys/quotactl.s +++ b/ppc/sys/quotactl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(quotactl, 3) - blr diff --git a/ppc/sys/read.s b/ppc/sys/read.s index 4d485ab..aa15c49 100644 --- a/ppc/sys/read.s +++ b/ppc/sys/read.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(read, 3) - blr diff --git a/ppc/sys/readlink.s b/ppc/sys/readlink.s index b2aa989..4e48856 100644 --- a/ppc/sys/readlink.s +++ b/ppc/sys/readlink.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(readlink, 3) - blr diff --git a/ppc/sys/readv.s b/ppc/sys/readv.s index 8b86196..5a2a211 100644 --- a/ppc/sys/readv.s +++ b/ppc/sys/readv.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(readv, 3) - blr diff --git a/ppc/sys/recvfrom.s b/ppc/sys/recvfrom.s index b2d6e21..796191b 100644 --- a/ppc/sys/recvfrom.s +++ b/ppc/sys/recvfrom.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(recvfrom, 6) - blr diff --git a/ppc/sys/recvmsg.s b/ppc/sys/recvmsg.s index 961b3a4..7cc1ea4 100644 --- a/ppc/sys/recvmsg.s +++ b/ppc/sys/recvmsg.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(recvmsg, 3) - blr diff --git a/ppc/sys/rename.s b/ppc/sys/rename.s index 2c2e875..631853b 100644 --- a/ppc/sys/rename.s +++ b/ppc/sys/rename.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(rename, 2) - blr diff --git a/ppc/sys/reset_shared_file.s b/ppc/sys/reset_shared_file.s index 48dab6c..5577bf8 100644 --- a/ppc/sys/reset_shared_file.s +++ b/ppc/sys/reset_shared_file.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(reset_shared_file, 3) - blr diff --git a/ppc/sys/revoke.s b/ppc/sys/revoke.s index 143c267..49a8b58 100644 --- a/ppc/sys/revoke.s +++ b/ppc/sys/revoke.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(revoke, 1) - blr diff --git a/ppc/sys/rmdir.s b/ppc/sys/rmdir.s index 9b7d53a..b38d788 100644 --- a/ppc/sys/rmdir.s +++ b/ppc/sys/rmdir.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(rmdir, 1) - blr diff --git a/ppc/sys/searchfs.s b/ppc/sys/searchfs.s index cdb5a79..7f8b789 100644 --- a/ppc/sys/searchfs.s +++ b/ppc/sys/searchfs.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(searchfs, 0) - blr diff --git a/ppc/sys/select.s b/ppc/sys/select.s index 6533e1d..89a2d31 100644 --- a/ppc/sys/select.s +++ b/ppc/sys/select.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(select, 5) - blr diff --git a/ppc/sys/sem_close.s b/ppc/sys/sem_close.s index f89be82..3fb00fe 100644 --- a/ppc/sys/sem_close.s +++ b/ppc/sys/sem_close.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_close, 1) - blr diff --git a/ppc/sys/sem_destroy.s b/ppc/sys/sem_destroy.s index 9ff703d..3fd2f13 100644 --- a/ppc/sys/sem_destroy.s +++ b/ppc/sys/sem_destroy.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_destroy, 1) - blr diff --git a/ppc/sys/sem_getvalue.s b/ppc/sys/sem_getvalue.s index a15854d..9551dd1 100644 --- a/ppc/sys/sem_getvalue.s +++ b/ppc/sys/sem_getvalue.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_getvalue, 2) - blr diff --git a/ppc/sys/sem_init.s b/ppc/sys/sem_init.s index 34bbf8a..218f0e9 100644 --- a/ppc/sys/sem_init.s +++ b/ppc/sys/sem_init.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_init, 3) - blr diff --git a/ppc/sys/sem_post.s b/ppc/sys/sem_post.s index a7597f9..a9e585c 100644 --- a/ppc/sys/sem_post.s +++ b/ppc/sys/sem_post.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_post, 1) - blr diff --git a/ppc/sys/sem_trywait.s b/ppc/sys/sem_trywait.s index ec572ab..1c8f5fe 100644 --- a/ppc/sys/sem_trywait.s +++ b/ppc/sys/sem_trywait.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_trywait, 1) - blr diff --git a/ppc/sys/sem_wait.s b/ppc/sys/sem_wait.s index bf7bbb2..3593a08 100644 --- a/ppc/sys/sem_wait.s +++ b/ppc/sys/sem_wait.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sem_wait, 1) - blr diff --git a/ppc/sys/semconfig.s b/ppc/sys/semconfig.s index 9cc3c49..314e4ba 100644 --- a/ppc/sys/semconfig.s +++ b/ppc/sys/semconfig.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(semconfig, 3) - blr diff --git a/ppc/sys/semctl.s b/ppc/sys/semctl.s index 38b543e..c0e6d9f 100644 --- a/ppc/sys/semctl.s +++ b/ppc/sys/semctl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(semctl, 3) - blr diff --git a/ppc/sys/semget.s b/ppc/sys/semget.s index 1172a7d..c86f9bc 100644 --- a/ppc/sys/semget.s +++ b/ppc/sys/semget.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(semget, 3) - blr diff --git a/ppc/sys/semop.s b/ppc/sys/semop.s index 422b04f..b8b9738 100644 --- a/ppc/sys/semop.s +++ b/ppc/sys/semop.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(semop, 3) - blr diff --git a/ppc/sys/semsys.s b/ppc/sys/semsys.s index 57194f8..1882ec9 100644 --- a/ppc/sys/semsys.s +++ b/ppc/sys/semsys.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(semsys, 3) - blr diff --git a/ppc/sys/sendmsg.s b/ppc/sys/sendmsg.s index 553c90a..0f9331c 100644 --- a/ppc/sys/sendmsg.s +++ b/ppc/sys/sendmsg.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sendmsg, 3) - blr diff --git a/ppc/sys/sendto.s b/ppc/sys/sendto.s index 638d69b..c1093e8 100644 --- a/ppc/sys/sendto.s +++ b/ppc/sys/sendto.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sendto, 6) - blr diff --git a/ppc/sys/setattrlist.s b/ppc/sys/setattrlist.s index 408e67f..c37ca78 100644 --- a/ppc/sys/setattrlist.s +++ b/ppc/sys/setattrlist.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(setattrlist, 0) - blr diff --git a/ppc/sys/setaudit.s b/ppc/sys/setaudit.s new file mode 100644 index 0000000..b0d323b --- /dev/null +++ b/ppc/sys/setaudit.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..20fe96a --- /dev/null +++ b/ppc/sys/setaudit_addr.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 new file mode 100644 index 0000000..c1ec307 --- /dev/null +++ b/ppc/sys/setauid.s @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET 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 index a340987..23a2d27 100644 --- a/ppc/sys/setegid.s +++ b/ppc/sys/setegid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setegid, 1) - blr diff --git a/ppc/sys/seteuid.s b/ppc/sys/seteuid.s index b67b5d8..85af2d9 100644 --- a/ppc/sys/seteuid.s +++ b/ppc/sys/seteuid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(seteuid, 1) - blr diff --git a/ppc/sys/setgid.s b/ppc/sys/setgid.s index 7a4d860..b883df5 100644 --- a/ppc/sys/setgid.s +++ b/ppc/sys/setgid.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(setgid, 1) - blr diff --git a/ppc/sys/setgroups.s b/ppc/sys/setgroups.s index 957cf7a..226ba88 100644 --- a/ppc/sys/setgroups.s +++ b/ppc/sys/setgroups.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setgroups, 2) - blr diff --git a/ppc/sys/setitimer.s b/ppc/sys/setitimer.s index 042d681..268153f 100644 --- a/ppc/sys/setitimer.s +++ b/ppc/sys/setitimer.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setitimer, 3) - blr diff --git a/ppc/sys/setjmp.s b/ppc/sys/setjmp.s index 6d367a1..0fd422a 100644 --- a/ppc/sys/setjmp.s +++ b/ppc/sys/setjmp.s @@ -60,9 +60,10 @@ L_setjmp: stw r31, JMP_r31(r3) stw r0, JMP_lr(r3) mr r31, r3 - li r3, 0 ; get the previous signal mask - CALL_EXTERN(_sigblock) - stw r3, JMP_sig(r31) ; save the previous 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 + CALL_EXTERN(_sigprocmask) mr r3, r31 lwz r0, JMP_lr(r3) mtlr r0 diff --git a/ppc/sys/setpgid.s b/ppc/sys/setpgid.s index 0cdcb1e..4df01d8 100644 --- a/ppc/sys/setpgid.s +++ b/ppc/sys/setpgid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setpgid, 2) - blr diff --git a/ppc/sys/setpriority.s b/ppc/sys/setpriority.s index 946185d..25a7a9e 100644 --- a/ppc/sys/setpriority.s +++ b/ppc/sys/setpriority.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setpriority, 3) - blr diff --git a/ppc/sys/setprivexec.s b/ppc/sys/setprivexec.s index 2e773c2..7525455 100644 --- a/ppc/sys/setprivexec.s +++ b/ppc/sys/setprivexec.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setprivexec, 3) - blr diff --git a/ppc/sys/setquota.s b/ppc/sys/setquota.s index 9de530c..727b9f5 100644 --- a/ppc/sys/setquota.s +++ b/ppc/sys/setquota.s @@ -27,4 +27,3 @@ #define SYS_setquota 148 SYSCALL(setquota, 2) - blr diff --git a/ppc/sys/setrlimit.s b/ppc/sys/setrlimit.s index 5f3f196..ba6ccde 100644 --- a/ppc/sys/setrlimit.s +++ b/ppc/sys/setrlimit.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setrlimit, 2) - blr diff --git a/ppc/sys/setsid.s b/ppc/sys/setsid.s index dbfc242..c1d0d41 100644 --- a/ppc/sys/setsid.s +++ b/ppc/sys/setsid.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setsid, 0) - blr diff --git a/ppc/sys/setsockopt.s b/ppc/sys/setsockopt.s index 1badef5..15898a6 100644 --- a/ppc/sys/setsockopt.s +++ b/ppc/sys/setsockopt.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(setsockopt, 5) - blr diff --git a/ppc/sys/settimeofday.s b/ppc/sys/settimeofday.s index 627a671..574c6a5 100644 --- a/ppc/sys/settimeofday.s +++ b/ppc/sys/settimeofday.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(settimeofday, 2) - blr diff --git a/ppc/sys/setuid.s b/ppc/sys/setuid.s index 8ce5460..44b6f3f 100644 --- a/ppc/sys/setuid.s +++ b/ppc/sys/setuid.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(setuid, 1) - blr diff --git a/ppc/sys/shmat.s b/ppc/sys/shmat.s index 2389fcd..5a8bbb6 100644 --- a/ppc/sys/shmat.s +++ b/ppc/sys/shmat.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(shmat, 3) - blr diff --git a/ppc/sys/shmctl.s b/ppc/sys/shmctl.s index cf95c8a..f2f6e59 100644 --- a/ppc/sys/shmctl.s +++ b/ppc/sys/shmctl.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(shmctl, 3) - blr diff --git a/ppc/sys/shmdt.s b/ppc/sys/shmdt.s index 6ffdd56..66c7c77 100644 --- a/ppc/sys/shmdt.s +++ b/ppc/sys/shmdt.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(shmdt, 3) - blr diff --git a/ppc/sys/shmget.s b/ppc/sys/shmget.s index 5335cfd..e0cb88f 100644 --- a/ppc/sys/shmget.s +++ b/ppc/sys/shmget.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(shmget, 3) - blr diff --git a/ppc/sys/shmsys.s b/ppc/sys/shmsys.s index d170579..1f2ecb9 100644 --- a/ppc/sys/shmsys.s +++ b/ppc/sys/shmsys.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(shmsys, 3) - blr diff --git a/ppc/sys/shutdown.s b/ppc/sys/shutdown.s index f9236f1..63ca4c2 100644 --- a/ppc/sys/shutdown.s +++ b/ppc/sys/shutdown.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(shutdown, 2) - blr diff --git a/ppc/sys/sigaltstack.s b/ppc/sys/sigaltstack.s index 71781f9..a9c52e7 100644 --- a/ppc/sys/sigaltstack.s +++ b/ppc/sys/sigaltstack.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(sigaltstack, 3) - blr diff --git a/ppc/sys/sigpending.s b/ppc/sys/sigpending.s index 33fd16a..f3a08cc 100644 --- a/ppc/sys/sigpending.s +++ b/ppc/sys/sigpending.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(sigpending, 1) - blr diff --git a/ppc/sys/sigprocmask.s b/ppc/sys/sigprocmask.s index e20efd1..052588f 100644 --- a/ppc/sys/sigprocmask.s +++ b/ppc/sys/sigprocmask.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sigprocmask, 3) - blr diff --git a/ppc/sys/sigwait.s b/ppc/sys/sigwait.s index 80bb450..ef51ca4 100644 --- a/ppc/sys/sigwait.s +++ b/ppc/sys/sigwait.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sigwait, 2) - blr diff --git a/ppc/sys/socket.s b/ppc/sys/socket.s index 0bad114..d0d7a67 100644 --- a/ppc/sys/socket.s +++ b/ppc/sys/socket.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(socket, 3) - blr diff --git a/ppc/sys/socketpair.s b/ppc/sys/socketpair.s index 69efec8..814957c 100644 --- a/ppc/sys/socketpair.s +++ b/ppc/sys/socketpair.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(socketpair, 5) - blr diff --git a/ppc/sys/stat.s b/ppc/sys/stat.s index 284d126..0f75255 100644 --- a/ppc/sys/stat.s +++ b/ppc/sys/stat.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(stat, 2) - blr diff --git a/ppc/sys/statfs.s b/ppc/sys/statfs.s index 3d097f2..4395ab3 100644 --- a/ppc/sys/statfs.s +++ b/ppc/sys/statfs.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(statfs, 2) - blr diff --git a/ppc/sys/statv.s b/ppc/sys/statv.s index 72188d8..40ddffd 100644 --- a/ppc/sys/statv.s +++ b/ppc/sys/statv.s @@ -27,4 +27,3 @@ #include "SYS.h" SYSCALL(statv, 0) - blr diff --git a/ppc/sys/swapon.s b/ppc/sys/swapon.s index 1feadd0..6d7a4e3 100644 --- a/ppc/sys/swapon.s +++ b/ppc/sys/swapon.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(swapon, 1) - blr diff --git a/ppc/sys/symlink.s b/ppc/sys/symlink.s index 4c7b636..24b1c28 100644 --- a/ppc/sys/symlink.s +++ b/ppc/sys/symlink.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(symlink, 2) - blr diff --git a/ppc/sys/sync.s b/ppc/sys/sync.s index e783b76..d377a71 100644 --- a/ppc/sys/sync.s +++ b/ppc/sys/sync.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(sync, 0) - blr diff --git a/ppc/sys/systable.s b/ppc/sys/systable.s index e17be22..3f0d139 100644 --- a/ppc/sys/systable.s +++ b/ppc/sys/systable.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(table, 5) - blr diff --git a/ppc/sys/truncate.s b/ppc/sys/truncate.s index 8de2f07..0df4841 100644 --- a/ppc/sys/truncate.s +++ b/ppc/sys/truncate.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(truncate, 2) - blr diff --git a/ppc/sys/umask.s b/ppc/sys/umask.s index e8c7786..1efb115 100644 --- a/ppc/sys/umask.s +++ b/ppc/sys/umask.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(umask, 1) - blr diff --git a/ppc/sys/undelete.s b/ppc/sys/undelete.s index e38c0cc..6436458 100644 --- a/ppc/sys/undelete.s +++ b/ppc/sys/undelete.s @@ -25,4 +25,3 @@ #include "SYS.h" SYSCALL(undelete, 1) - blr diff --git a/ppc/sys/unlink.s b/ppc/sys/unlink.s index 847595e..6710a6b 100644 --- a/ppc/sys/unlink.s +++ b/ppc/sys/unlink.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(unlink, 1) - blr diff --git a/ppc/sys/unmount.s b/ppc/sys/unmount.s index cb89853..5540c16 100644 --- a/ppc/sys/unmount.s +++ b/ppc/sys/unmount.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(unmount, 1) - blr diff --git a/ppc/sys/utimes.s b/ppc/sys/utimes.s index 30fe9a2..0cf697e 100644 --- a/ppc/sys/utimes.s +++ b/ppc/sys/utimes.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(utimes, 2) - blr diff --git a/ppc/sys/wait4.s b/ppc/sys/wait4.s index 08917e8..04dae84 100644 --- a/ppc/sys/wait4.s +++ b/ppc/sys/wait4.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(wait4, 4) - blr diff --git a/ppc/sys/write.s b/ppc/sys/write.s index 236dfa0..5f2f96e 100644 --- a/ppc/sys/write.s +++ b/ppc/sys/write.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(write, 3) - blr diff --git a/ppc/sys/writev.s b/ppc/sys/writev.s index 8554302..f0f3a84 100644 --- a/ppc/sys/writev.s +++ b/ppc/sys/writev.s @@ -25,5 +25,4 @@ #include "SYS.h" SYSCALL(writev, 3) - blr diff --git a/pthreads/Makefile.inc b/pthreads/Makefile.inc index acd3d05..c876b73 100644 --- a/pthreads/Makefile.inc +++ b/pthreads/Makefile.inc @@ -1,5 +1,9 @@ .PATH: ${.CURDIR}/${MACHINE_ARCH}/pthreads ${.CURDIR}/pthreads +.if exists(${.CURDIR}/${MACHINE_ARCH}/pthreads/Makefile.inc) +.include "${.CURDIR}/${MACHINE_ARCH}/pthreads/Makefile.inc" +.endif + SRCS += pthread_cond.c pthread_tsd.c pthread.c \ pthread_mutex.c thread_setup.c lock.s stack.s pthread_rwlock.c @@ -51,9 +55,11 @@ 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_setprotocol.3 \ + pthread_mutexattr.3 pthread_mutexattr_settype.3 MLINKS+=pthread_setcancelstate.3 pthread_setcanceltype.3 \ pthread_setcancelstate.3 pthread_testcancel.3 diff --git a/pthreads/lock.s b/pthreads/lock.s index 257bc1b..6a88805 100644 --- a/pthreads/lock.s +++ b/pthreads/lock.s @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -19,9 +43,10 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ -/* - * MkLinux - */ + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE #if defined(__ppc__) @@ -32,40 +57,19 @@ * * 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) -1: - lwarx r5,0,r3 // Read the lock - addi r4,0,0x1 // Lock value - cmpwi r5,0x0 // Is it busy? - bne- 2f // Yes, return 0 - stwcx. r4,0,r3 // Try to lock the lock - bne- 1b // Lost reservation, try again - addi r3,0,1 // Got the lock - isync // Sync instruction stream - blr // Return 1 -2: addi r3,0,0 // Could not get the lock - blr // Return 0 + ba _COMM_PAGE_SPINLOCK_TRY END(__spin_lock_try) .globl _spin_lock LEAF(__spin_lock) _spin_lock: -1: - lwarx r5,0,r3 // Read the lock - addi r4,0,0x1 // Lock value - cmpwi r5,0x0 // Is it busy? - bne- 2f // Yes, goto retry logic - stwcx. r4,0,r3 // Try to lock the lock - bne- 1b // Lost reservation, try again - isync // Sync instruction stream - blr // Return -2: - CALL_EXTERN(__spin_lock_retry) - blr // Return + ba _COMM_PAGE_SPINLOCK_LOCK END(__spin_lock) /* void spin_unlock(int *p); @@ -75,10 +79,7 @@ END(__spin_lock) .globl _spin_unlock LEAF(__spin_unlock) _spin_unlock: - sync - li32 r4,0 - stw r4,0(r3) - blr + ba _COMM_PAGE_SPINLOCK_UNLOCK END(__spin_unlock) #elif defined(__i386__) @@ -94,33 +95,21 @@ END(__spin_unlock) * lock is available. */ TEXT + ALIGN .globl _spin_lock_try LEAF(__spin_lock_try, 0) _spin_lock_try: - movl 4(%esp),%ecx - movl $1,%eax - xchgl (%ecx),%eax - xorl $1,%eax -END(__spin_lock_try) + movl $(_COMM_PAGE_SPINLOCK_TRY), %eax + jmpl %eax + + ALIGN .globl _spin_lock LEAF(__spin_lock, 0) _spin_lock: - movl 4(%esp), %ecx - movl (%ecx), %eax - orl %eax, %eax - jnz 1f - movl $0xFFFFFFFF, %eax - xchgl %eax, (%ecx) - orl %eax, %eax - jz 2f -1: pushl %ecx - CALL_EXTERN(__spin_lock_retry) - addl $4, %esp -2: -END(__spin_lock) - + movl $(_COMM_PAGE_SPINLOCK_LOCK), %eax + jmpl %eax /* * void @@ -129,13 +118,13 @@ END(__spin_lock) * * Unlock the lock pointed to by p. */ + ALIGN + .globl _spin_unlock LEAF(__spin_unlock, 0) _spin_unlock: - movl $0, %eax - movl 4(%esp), %ecx - xchgl %eax, (%ecx) -END(__spin_unlock) + movl $(_COMM_PAGE_SPINLOCK_UNLOCK), %eax + jmpl %eax #else #error spin_locks not defined for this architecture diff --git a/pthreads/mk_pthread_impl.c b/pthreads/mk_pthread_impl.c index 67b8c1b..adc5670 100644 --- a/pthreads/mk_pthread_impl.c +++ b/pthreads/mk_pthread_impl.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 diff --git a/pthreads/posix_sched.h b/pthreads/posix_sched.h index b9badf1..b0cbad6 100644 --- a/pthreads/posix_sched.h +++ b/pthreads/posix_sched.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 diff --git a/pthreads/pthread.c b/pthreads/pthread.c index c067de1..88242fd 100644 --- a/pthreads/pthread.c +++ b/pthreads/pthread.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -27,7 +51,8 @@ * POSIX Pthread Library */ -#define __POSIX_LIB__ +#include "pthread_internals.h" + #include #include /* For printf(). */ #include @@ -35,16 +60,22 @@ #include #include #include +#include #include #include #include +#define __APPLE_API_PRIVATE +#include -#include "pthread_internals.h" +__private_extern__ struct __pthread_list __pthread_head = LIST_HEAD_INITIALIZER(&__pthread_head); /* Per-thread kernel support */ extern void _pthread_set_self(pthread_t); extern void mig_init(int); +/* Get CPU capabilities from the kernel */ +__private_extern__ void _init_cpu_capabilities(void); + /* Needed to tell the malloc subsystem we're going multithreaded */ extern void set_malloc_singlethreaded(int); @@ -59,9 +90,10 @@ static struct _pthread _thread = {0}; ** pthread has been created. */ int __is_threaded = 0; +/* _pthread_count is protected by _pthread_list_lock */ static int _pthread_count = 1; -static pthread_lock_t _pthread_count_lock = LOCK_INITIALIZER; +__private_extern__ pthread_lock_t _pthread_list_lock = LOCK_INITIALIZER; /* Same implementation as LOCK, but without the __is_threaded check */ int _spin_tries = 0; @@ -76,9 +108,6 @@ __private_extern__ void _spin_lock_retry(pthread_lock_t *lock) } while(!_spin_lock_try(lock)); } -/* Apparently, bcopy doesn't declare _cpu_has_altivec anymore */ -int _cpu_has_altivec = 0; - extern mach_port_t thread_recycle_port; /* These are used to keep track of a semaphore pool shared by mutexes and condition @@ -102,18 +131,6 @@ size_t _pthread_stack_size = 0; #define STACK_LOWEST(sp) ((sp) & ~__pthread_stack_mask) #define STACK_RESERVED (sizeof (struct _pthread)) -#ifdef STACK_GROWS_UP - -/* The stack grows towards higher addresses: - |struct _pthread|user stack---------------->| - ^STACK_BASE ^STACK_START - ^STACK_SELF - ^STACK_LOWEST */ -#define STACK_BASE(sp) STACK_LOWEST(sp) -#define STACK_START(stack_low) (STACK_BASE(stack_low) + STACK_RESERVED) -#define STACK_SELF(sp) STACK_BASE(sp) - -#else /* The stack grows towards lower addresses: |<----------------user stack|struct _pthread| @@ -124,8 +141,6 @@ size_t _pthread_stack_size = 0; #define STACK_START(stack_low) (STACK_BASE(stack_low) - STACK_RESERVED) #define STACK_SELF(sp) STACK_START(sp) -#endif - #if defined(__ppc__) static const vm_address_t PTHREAD_STACK_HINT = 0xF0000000; #elif defined(__i386__) @@ -134,44 +149,46 @@ static const vm_address_t PTHREAD_STACK_HINT = 0xB0000000; #error Need to define a stack address hint for this architecture #endif -/* Set the base address to use as the stack pointer, before adjusting due to the ABI */ +/* Set the base address to use as the stack pointer, before adjusting due to the ABI + * The guardpages for stackoverflow protection is also allocated here + * If the stack was already allocated(stackaddr in attr) then there are no guardpages + * set up for the thread + */ static int _pthread_allocate_stack(pthread_attr_t *attrs, void **stack) { kern_return_t kr; + size_t guardsize; #if 1 assert(attrs->stacksize >= PTHREAD_STACK_MIN); if (attrs->stackaddr != NULL) { + /* No guard pages setup in this case */ assert(((vm_address_t)(attrs->stackaddr) & (vm_page_size - 1)) == 0); *stack = attrs->stackaddr; return 0; } + guardsize = attrs->guardsize; *((vm_address_t *)stack) = PTHREAD_STACK_HINT; kr = vm_map(mach_task_self(), (vm_address_t *)stack, - attrs->stacksize + vm_page_size, + attrs->stacksize + guardsize, 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(), - (vm_address_t *)stack, attrs->stacksize + vm_page_size, + (vm_address_t *)stack, attrs->stacksize + guardsize, VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE); if (kr != KERN_SUCCESS) { return EAGAIN; } - #ifdef STACK_GROWS_UP - /* The guard page is the page one higher than the stack */ - /* The stack base is at the lowest address */ - kr = vm_protect(mach_task_self(), *stack + attrs->stacksize, vm_page_size, FALSE, VM_PROT_NONE); - #else /* The guard page is at the lowest address */ /* The stack base is the highest address */ - kr = vm_protect(mach_task_self(), (vm_address_t)*stack, vm_page_size, FALSE, VM_PROT_NONE); - *stack += attrs->stacksize + vm_page_size; - #endif + if (guardsize) + kr = vm_protect(mach_task_self(), (vm_address_t)*stack, guardsize, FALSE, VM_PROT_NONE); + *stack += attrs->stacksize + guardsize; #else vm_address_t cur_stack = (vm_address_t)0; @@ -202,18 +219,11 @@ _pthread_allocate_stack(pthread_attr_t *attrs, void **stack) FALSE); #ifndef NO_GUARD_PAGES if (kr == KERN_SUCCESS) { -# ifdef STACK_GROWS_UP - kr = vm_protect(mach_task_self(), - lowest_stack+__pthread_stack_size, - __pthread_stack_size, - FALSE, VM_PROT_NONE); -# else /* STACK_GROWS_UP */ kr = vm_protect(mach_task_self(), lowest_stack, __pthread_stack_size, FALSE, VM_PROT_NONE); lowest_stack += __pthread_stack_size; -# endif /* STACK_GROWS_UP */ if (kr == KERN_SUCCESS) break; } @@ -239,18 +249,11 @@ _pthread_allocate_stack(pthread_attr_t *attrs, void **stack) know what to do. */ #ifndef NO_GUARD_PAGES if (kr == KERN_SUCCESS) { -# ifdef STACK_GROWS_UP - kr = vm_protect(mach_task_self(), - lowest_stack+__pthread_stack_size, - __pthread_stack_size, - FALSE, VM_PROT_NONE); -# else /* STACK_GROWS_UP */ kr = vm_protect(mach_task_self(), lowest_stack, __pthread_stack_size, FALSE, VM_PROT_NONE); lowest_stack += __pthread_stack_size; -# endif /* STACK_GROWS_UP */ } #endif free_stacks = (vm_address_t *)lowest_stack; @@ -354,7 +357,8 @@ pthread_attr_getschedpolicy(const pthread_attr_t *attr, } } -static const size_t DEFAULT_STACK_SIZE = DFLSSIZ; +/* Retain the existing stack size of 512K and not depend on Main thread default stack size */ +static const size_t DEFAULT_STACK_SIZE = (512*1024); /* * Initialize a thread attribute structure to default values. */ @@ -364,12 +368,13 @@ pthread_attr_init(pthread_attr_t *attr) attr->stacksize = DEFAULT_STACK_SIZE; attr->stackaddr = NULL; attr->sig = _PTHREAD_ATTR_SIG; - attr->policy = _PTHREAD_DEFAULT_POLICY; attr->param.sched_priority = default_priority; attr->param.quantum = 10; /* quantum isn't public yet */ - attr->inherit = _PTHREAD_DEFAULT_INHERITSCHED; attr->detached = PTHREAD_CREATE_JOINABLE; + attr->inherit = _PTHREAD_DEFAULT_INHERITSCHED; + attr->policy = _PTHREAD_DEFAULT_POLICY; attr->freeStackOnExit = TRUE; + attr->guardsize = vm_page_size; return (ESUCCESS); } @@ -552,7 +557,10 @@ int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t * stacksize) { if (attr->sig == _PTHREAD_ATTR_SIG) { - *stackaddr = attr->stackaddr; + u_int32_t addr = (u_int32_t)attr->stackaddr; + + addr -= attr->stacksize; + *stackaddr = (void *)addr; *stacksize = attr->stacksize; return (ESUCCESS); } else { @@ -560,21 +568,61 @@ pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t * sta } } +/* By SUSV spec, the stackaddr is the base address, the lowest addressable + * byte address. This is not the same as in pthread_attr_setstackaddr. + */ int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize) { if ((attr->sig == _PTHREAD_ATTR_SIG) && (((vm_offset_t)stackaddr & (vm_page_size - 1)) == 0) && ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) { - attr->stackaddr = stackaddr; - attr->freeStackOnExit = FALSE; + u_int32_t addr = (u_int32_t)stackaddr; + + addr += stacksize; + attr->stackaddr = (void *)addr; attr->stacksize = stacksize; + attr->freeStackOnExit = FALSE; return (ESUCCESS); } else { return (EINVAL); /* Not an attribute structure! */ } } + +/* + * Set the guardsize attribute in the attr. + */ +int +pthread_attr_setguardsize(pthread_attr_t *attr, + size_t guardsize) +{ + if (attr->sig == _PTHREAD_ATTR_SIG) { + /* Guardsize of 0 is valid, ot means no guard */ + if ((guardsize % vm_page_size) == 0) { + attr->guardsize = guardsize; + return (ESUCCESS); + } else + return(EINVAL); + } + return (EINVAL); /* Not an attribute structure! */ +} + +/* + * Get the guardsize attribute in the attr. + */ +int +pthread_attr_getguardsize(const pthread_attr_t *attr, + size_t *guardsize) +{ + if (attr->sig == _PTHREAD_ATTR_SIG) { + *guardsize = attr->guardsize; + return (ESUCCESS); + } + return (EINVAL); /* Not an attribute structure! */ +} + + /* * Create and start execution of a new thread. */ @@ -598,8 +646,10 @@ _pthread_create(pthread_t t, do { memset(t, 0, sizeof(*t)); + t->tsd[0] = t; t->stacksize = attrs->stacksize; t->stackaddr = (void *)stack; + t->guardsize = attrs->guardsize; t->kernel_thread = kernel_thread; t->detached = attrs->detached; t->inherit = attrs->inherit; @@ -611,6 +661,8 @@ _pthread_create(pthread_t t, 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->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; t->cleanup_stack = (struct _pthread_handler_rec *)NULL; t->death = SEMAPHORE_NULL; @@ -736,14 +788,15 @@ _pthread_create_suspended(pthread_t *thread, } set_malloc_singlethreaded(0); __is_threaded = 1; - LOCK(_pthread_count_lock); - _pthread_count++; - UNLOCK(_pthread_count_lock); /* Send it on it's way */ t->arg = arg; t->fun = start_routine; /* Now set it up to execute */ + LOCK(_pthread_list_lock); + LIST_INSERT_HEAD(&__pthread_head, t, plist); + _pthread_count++; + UNLOCK(_pthread_list_lock); _pthread_setup(t, _pthread_body, stack, suspended, needresume); } while (0); return (res); @@ -806,6 +859,7 @@ pthread_detach(pthread_t thread) * pthread_kill call to system call */ +extern int __pthread_kill(mach_port_t, int); int pthread_kill ( @@ -881,11 +935,9 @@ int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_p vm_address_t addr = (vm_address_t)th->stackaddr; vm_size_t size; - size = (vm_size_t)th->stacksize + vm_page_size; + size = (vm_size_t)th->stacksize + th->guardsize; -#if !defined(STACK_GROWS_UP) addr -= size; -#endif ret = vm_deallocate(self, addr, size); if (ret != KERN_SUCCESS) { fprintf(stderr, @@ -973,15 +1025,19 @@ pthread_exit(void *value_ptr) "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); + 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)); } - LOCK(_pthread_count_lock); - thread_count = --_pthread_count; - UNLOCK(_pthread_count_lock); if (thread_count <= 0) exit(0); @@ -1029,6 +1085,9 @@ pthread_join(pthread_t thread, } while (kern_res != KERN_SUCCESS); } + LOCK(_pthread_list_lock); + LIST_REMOVE(thread, plist); + UNLOCK(_pthread_list_lock); /* ... and wait for it to really be dead */ while ((res = _pthread_reap_thread(thread, thread->kernel_thread, @@ -1106,13 +1165,13 @@ pthread_setschedparam(pthread_t thread, default: return (EINVAL); } - thread->policy = policy; - thread->param = *param; 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 { @@ -1148,6 +1207,18 @@ pthread_equal(pthread_t t1, return (t1 == t2); } +__private_extern__ void +_pthread_set_self(pthread_t p) +{ + extern void __pthread_set_self(pthread_t); + if (p == 0) { + bzero(&_thread, sizeof(struct _pthread)); + p = &_thread; + } + p->tsd[0] = p; + __pthread_set_self(p); +} + void cthread_set_self(void *cself) { @@ -1175,13 +1246,13 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { - LOCK(once_control->lock); + _spin_lock(&once_control->lock); if (once_control->sig == _PTHREAD_ONCE_SIG_init) { (*init_routine)(); once_control->sig = _PTHREAD_ONCE_SIG; } - UNLOCK(once_control->lock); + _spin_unlock(&once_control->lock); return (ESUCCESS); /* Spec defines no possible errors! */ } @@ -1287,12 +1358,6 @@ pthread_setconcurrency(int new_level) * Perform package initialization - called automatically when application starts */ -extern int _cpu_capabilities; - -#define kHasAltivec 0x01 -#define kCache32 0x04 -#define kUseDcba 0x20 - static int pthread_init(void) { @@ -1308,9 +1373,6 @@ pthread_init(void) int mib[2]; size_t len; int numcpus; - - extern int _bcopy_initialize(void); - count = HOST_PRIORITY_INFO_COUNT; info = (host_info_t)&priority_info; @@ -1321,13 +1383,16 @@ pthread_init(void) printf("host_info failed (%d); probably need privilege.\n", kr); else { default_priority = priority_info.user_priority; - min_priority = priority_info.minimum_priority; - max_priority = priority_info.maximum_priority; + min_priority = priority_info.minimum_priority; + max_priority = priority_info.maximum_priority; } attrs = &_pthread_attr_default; pthread_attr_init(attrs); + LIST_INIT(&__pthread_head); + LOCK_INIT(_pthread_list_lock); thread = &_thread; + LIST_INSERT_HEAD(&__pthread_head, thread, plist); _pthread_set_self(thread); _pthread_create(thread, attrs, (void *)USRSTACK, mach_thread_self()); thread->detached = PTHREAD_CREATE_JOINABLE|_PTHREAD_CREATE_PARENT; @@ -1350,18 +1415,27 @@ pthread_init(void) else { if (basic_info.avail_cpus > 1) _spin_tries = MP_SPIN_TRIES; - /* This is a crude test */ - if (basic_info.cpu_subtype >= CPU_SUBTYPE_POWERPC_7400) - _cpu_has_altivec = 1; } } - mach_port_deallocate(mach_task_self(), host); - - len = sizeof(_cpu_capabilities); - sysctlbyname("hw._cpu_capabilities", &_cpu_capabilities, &len, NULL, 0); - _bcopy_initialize(); + mach_port_deallocate(mach_task_self(), host); + + _init_cpu_capabilities(); +#if defined(__ppc__) + + /* Use fsqrt instruction in sqrt() if available. */ + if (_cpu_capabilities & kHasFsqrt) { + extern size_t hw_sqrt_len; + extern double sqrt( double ); + extern double hw_sqrt( double ); + extern void sys_icache_invalidate(void *, size_t); + + memcpy ( (void *)sqrt, (void *)hw_sqrt, hw_sqrt_len ); + sys_icache_invalidate((void *)sqrt, hw_sqrt_len); + } +#endif + mig_init(1); /* enable multi-threaded mig interfaces */ return 0; } @@ -1410,11 +1484,16 @@ static void sem_pool_reset(void) { UNLOCK(sem_pool_lock); } -__private_extern__ void _pthread_fork_child(void) { +__private_extern__ void _pthread_fork_child(pthread_t p) { /* Just in case somebody had it locked... */ UNLOCK(sem_pool_lock); sem_pool_reset(); - UNLOCK(_pthread_count_lock); + /* No need to hold the pthread_list_lock as no one other than this + * thread is present at this time + */ + LIST_INIT(&__pthread_head); + LOCK_INIT(_pthread_list_lock); + LIST_INSERT_HEAD(&__pthread_head, p, plist); _pthread_count = 1; } diff --git a/pthreads/pthread.h b/pthreads/pthread.h index d110560..b927a65 100644 --- a/pthreads/pthread.h +++ b/pthreads/pthread.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -143,7 +167,7 @@ __BEGIN_DECLS * Mutex variables */ -#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {}} +#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}} /* * Condition variable attributes @@ -153,13 +177,13 @@ __BEGIN_DECLS * Condition variables */ -#define PTHREAD_COND_INITIALIZER {_PTHREAD_COND_SIG_init, {}} +#define PTHREAD_COND_INITIALIZER {_PTHREAD_COND_SIG_init, {0}} /* * Initialization control (once) variables */ -#define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {}} +#define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}} /* * Thread Specific Data - keys @@ -170,158 +194,159 @@ __BEGIN_DECLS /* * Prototypes for all PTHREAD interfaces */ -int pthread_attr_destroy __P((pthread_attr_t *attr)); -int pthread_attr_getdetachstate __P((const pthread_attr_t *attr, - int *detachstate)); -int pthread_attr_getinheritsched __P((const pthread_attr_t *attr, - int *inheritsched)); -int pthread_attr_getschedparam __P((const pthread_attr_t *attr, - struct sched_param *param)); -int pthread_attr_getschedpolicy __P((const pthread_attr_t *attr, - int *policy)); -int pthread_attr_getstackaddr __P((const pthread_attr_t *attr, - void **stackaddr)); -int pthread_attr_getstacksize __P((const pthread_attr_t *attr, - size_t *stacksize)); -int pthread_attr_getstack __P((const pthread_attr_t *attr, - void **stackaddr, size_t *stacksize)); -int pthread_attr_init __P((pthread_attr_t *attr)); -int pthread_attr_setdetachstate __P((pthread_attr_t *attr, - int detachstate)); -int pthread_attr_setinheritsched __P((pthread_attr_t *attr, - int inheritsched)); -int pthread_attr_setschedparam __P((pthread_attr_t *attr, - const struct sched_param *param)); -int pthread_attr_setschedpolicy __P((pthread_attr_t *attr, - int policy)); -int pthread_attr_setstackaddr __P((pthread_attr_t *attr, - void *stackaddr)); -int pthread_attr_setstacksize __P((pthread_attr_t *attr, - size_t stacksize)); -int pthread_attr_setstack __P((pthread_attr_t *attr, - void *stackaddr, size_t stacksize)); -int pthread_cancel __P((pthread_t thread)); -int pthread_setcancelstate __P((int state, int *oldstate)); -int pthread_setcanceltype __P((int type, int *oldtype)); -void pthread_testcancel __P((void)); -int pthread_cond_broadcast __P((pthread_cond_t *cond)); -int pthread_cond_destroy __P((pthread_cond_t *cond)); -int pthread_cond_init __P((pthread_cond_t *cond, - const pthread_condattr_t *attr)); -int pthread_cond_signal __P((pthread_cond_t *cond)); -int pthread_cond_wait __P((pthread_cond_t *cond, - pthread_mutex_t *mutex)); -int pthread_cond_timedwait __P((pthread_cond_t *cond, +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_getdetachstate(const pthread_attr_t *attr, + int *detachstate); +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_getstackaddr(const pthread_attr_t *attr, + void **stackaddr); +int pthread_attr_getstacksize(const pthread_attr_t *attr, + size_t *stacksize); +int pthread_attr_getstack(const pthread_attr_t *attr, + void **stackaddr, size_t *stacksize); +int pthread_attr_getguardsize(const pthread_attr_t *attr, + size_t *guardsize); +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_setdetachstate(pthread_attr_t *attr, + int detachstate); +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_attr_setstackaddr(pthread_attr_t *attr, + void *stackaddr); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); +int pthread_attr_setstack(pthread_attr_t *attr, + void *stackaddr, size_t stacksize); +int pthread_cancel(pthread_t thread); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); +void pthread_testcancel(void); +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_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 pthread_condattr_init __P((pthread_condattr_t *attr)); -int pthread_condattr_destroy __P((pthread_condattr_t *attr)); -int pthread_condattr_getpshared __P((const pthread_condattr_t *attr, - int *pshared)); -int pthread_condattr_setpshared __P((pthread_condattr_t *attr, - int pshared)); -int pthread_create __P((pthread_t *thread, + const struct timespec *abstime); +int pthread_condattr_init(pthread_condattr_t *attr); +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_getpshared(const pthread_condattr_t *attr, + int *pshared); +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 __P((pthread_t thread)); -int pthread_equal __P((pthread_t t1, - pthread_t t2)); -void pthread_exit __P((void *value_ptr)); -int pthread_kill __P((pthread_t, int)); -int pthread_sigmask __P((int, const sigset_t *, sigset_t *)); -int sigwait __P((const sigset_t *, int *)); -int pthread_getschedparam __P((pthread_t thread, + 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_kill(pthread_t, int); +int pthread_sigmask(int, const sigset_t *, sigset_t *); +int pthread_getschedparam(pthread_t thread, int *policy, - struct sched_param *param)); -int pthread_join __P((pthread_t thread, - void **value_ptr)); -int pthread_mutex_destroy __P((pthread_mutex_t *mutex)); -int pthread_mutex_getprioceiling __P((const pthread_mutex_t *mutex, - int *prioceiling)); -int pthread_mutex_init __P((pthread_mutex_t *mutex, - const pthread_mutexattr_t *attr)); -int pthread_mutex_lock __P((pthread_mutex_t *mutex)); -int pthread_mutex_setprioceiling __P((pthread_mutex_t *mutex, + struct sched_param *param); +int pthread_join(pthread_t thread, + void **value_ptr); +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 __P((pthread_mutex_t *mutex)); -int pthread_mutex_unlock __P((pthread_mutex_t *mutex)); -int pthread_mutexattr_destroy __P((pthread_mutexattr_t *attr)); -int pthread_mutexattr_getprioceiling __P((const pthread_mutexattr_t *attr, - int *prioceiling)); -int pthread_mutexattr_getprotocol __P((const pthread_mutexattr_t *attr, - int *protocol)); -int pthread_mutexattr_getpshared __P((const pthread_mutexattr_t *attr, - int *pshared)); -int pthread_mutexattr_gettype __P((const pthread_mutexattr_t *attr, - int *type)); -int pthread_mutexattr_init __P((pthread_mutexattr_t *attr)); -int pthread_mutexattr_setprioceiling __P((pthread_mutexattr_t *attr, - int prioceiling)); -int pthread_mutexattr_setprotocol __P((pthread_mutexattr_t *attr, - int protocol)); -int pthread_mutexattr_settype __P((pthread_mutexattr_t *attr, - int type)); -int pthread_mutexattr_setpshared __P((pthread_mutexattr_t *attr, - int pshared)); -int pthread_once __P((pthread_once_t *once_control, - void (*init_routine)(void))); -pthread_t pthread_self __P((void)); -int pthread_setschedparam __P((pthread_t thread, + 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_settype(pthread_mutexattr_t *attr, + int type); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, + int pshared); +int pthread_once(pthread_once_t *once_control, + void (*init_routine)(void)); +pthread_t pthread_self(void); +int pthread_setschedparam(pthread_t thread, int policy, - const struct sched_param *param)); -int pthread_key_create __P((pthread_key_t *key, - void (*destructor)(void *))); -int pthread_key_delete __P((pthread_key_t key)); -int pthread_setspecific __P((pthread_key_t key, - const void *value)); -void *pthread_getspecific __P((pthread_key_t key)); -int pthread_attr_getscope __P((pthread_attr_t *, int *)); -int pthread_attr_setscope __P((pthread_attr_t *, int)); -int pthread_getconcurrency __P((void)); -int pthread_setconcurrency __P((int)); -int pthread_rwlock_destroy __P((pthread_rwlock_t * rwlock)); -int pthread_rwlock_init __P((pthread_rwlock_t * rwlock, - const pthread_rwlockattr_t *attr)); -int pthread_rwlock_rdlock __P((pthread_rwlock_t *rwlock)); -int pthread_rwlock_tryrdlock __P((pthread_rwlock_t *rwlock)); -int pthread_rwlock_wrlock __P((pthread_rwlock_t *rwlock)); -int pthread_rwlock_trywrlock __P((pthread_rwlock_t *rwlock)); -int pthread_rwlock_unlock __P((pthread_rwlock_t *rwlock)); -int pthread_rwlockattr_init __P((pthread_rwlockattr_t *attr)); -int pthread_rwlockattr_destroy __P((pthread_rwlockattr_t *attr)); -int pthread_rwlockattr_getpshared __P((const pthread_rwlockattr_t *attr, - int *pshared)); -int pthread_rwlockattr_setpshared __P((pthread_rwlockattr_t *attr, - int pshared)); + const struct sched_param *param); +int pthread_key_create(pthread_key_t *key, + void (*destructor)(void *)); +int pthread_key_delete(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, + const void *value); +void *pthread_getspecific(pthread_key_t key); +int pthread_attr_getscope(pthread_attr_t *, int *); +int pthread_attr_setscope(pthread_attr_t *, int); +int pthread_getconcurrency(void); +int pthread_setconcurrency(int); +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_wrlock(pthread_rwlock_t *rwlock); +int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); +int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); +int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, + int *pshared); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, + int pshared); #ifndef _POSIX_C_SOURCE /* returns non-zero if pthread_create or cthread_fork have been called */ -int pthread_is_threaded_np __P((void)); +int pthread_is_threaded_np(void); /* returns non-zero if the current thread is the main thread */ -int pthread_main_np __P((void)); +int pthread_main_np(void); /* return the mach thread bound to the pthread */ -mach_port_t pthread_mach_thread_np __P((pthread_t)); -size_t pthread_get_stacksize_np __P((pthread_t)); -void * pthread_get_stackaddr_np __P((pthread_t)); +mach_port_t pthread_mach_thread_np(pthread_t); +size_t pthread_get_stacksize_np(pthread_t); +void * pthread_get_stackaddr_np(pthread_t); /* Like pthread_cond_signal(), but only wake up the specified pthread */ -int pthread_cond_signal_thread_np __P((pthread_cond_t *, 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 __P((pthread_cond_t *cond, +int pthread_cond_timedwait_relative_np(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *reltime)); + const struct timespec *reltime); /* Like pthread_create(), but leaves the thread suspended */ -int pthread_create_suspended_np __P((pthread_t *thread, +int pthread_create_suspended_np(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), - void *arg)); -void pthread_yield_np __P((void)); + void *arg); +void pthread_yield_np(void); #endif /* ! _POSIX_C_SOURCE */ __END_DECLS #endif /* _POSIX_PTHREAD_H */ diff --git a/pthreads/pthread_cond.c b/pthreads/pthread_cond.c index 409f231..9e3cc57 100644 --- a/pthreads/pthread_cond.c +++ b/pthreads/pthread_cond.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -30,45 +54,64 @@ #include /* For struct timespec and getclock(). */ #include - /* +extern void _pthread_mutex_remove(pthread_mutex_t *, pthread_t); + +/* * Destroy a condition variable. */ int pthread_cond_destroy(pthread_cond_t *cond) { + int ret; + int sig = cond->sig; + + /* to provide backwards compat for apps using united condtn vars */ + if((sig != _PTHREAD_COND_SIG) && (sig !=_PTHREAD_COND_SIG_init)) + return(EINVAL); + + LOCK(cond->lock); if (cond->sig == _PTHREAD_COND_SIG) { - LOCK(cond->lock); - if (cond->busy != (pthread_mutex_t *)NULL) - { - UNLOCK(cond->lock); - return (EBUSY); - } else + if (cond->busy == (pthread_mutex_t *)NULL) { cond->sig = _PTHREAD_NO_SIG; - UNLOCK(cond->lock); - return (ESUCCESS); - } + ret = ESUCCESS; + } else + ret = EBUSY; } else - return (EINVAL); /* Not an initialized condition variable structure */ + ret = EINVAL; /* Not an initialized condition variable structure */ + UNLOCK(cond->lock); + return (ret); } /* * Initialize a condition variable. Note: 'attr' is ignored. */ -int -pthread_cond_init(pthread_cond_t *cond, +static int +_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { - LOCK_INIT(cond->lock); - cond->sig = _PTHREAD_COND_SIG; 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 = MACH_PORT_NULL; - return (ESUCCESS); + 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)); } /* @@ -77,37 +120,50 @@ pthread_cond_init(pthread_cond_t *cond, int pthread_cond_broadcast(pthread_cond_t *cond) { - kern_return_t kern_res; - int res; - if (cond->sig == _PTHREAD_COND_SIG_init) { - if ((res = pthread_cond_init(cond, NULL)) != 0) { - return (res); - } - } - if (cond->sig != _PTHREAD_COND_SIG) { - /* Not a condition variable */ - return (EINVAL); - } - LOCK(cond->lock); - if (cond->sem == MACH_PORT_NULL) { - /* Avoid kernel call since there are no waiters... */ - UNLOCK(cond->lock); - return (ESUCCESS); - } - cond->sigspending++; - UNLOCK(cond->lock); - PTHREAD_MACH_CALL(semaphore_signal_all(cond->sem), kern_res); - LOCK(cond->lock); - cond->sigspending--; - if (cond->waiters == 0 && cond->sigspending == 0) { - restore_sem_to_pool(cond->sem); - cond->sem = MACH_PORT_NULL; - } - UNLOCK(cond->lock); - if (kern_res != KERN_SUCCESS) { - return (EINVAL); - } - return (ESUCCESS); + kern_return_t kern_res; + semaphore_t sem; + int sig = cond->sig; + + /* to provide backwards compat for apps using united condtn vars */ + if((sig != _PTHREAD_COND_SIG) && (sig !=_PTHREAD_COND_SIG_init)) + return(EINVAL); + + LOCK(cond->lock); + if (cond->sig != _PTHREAD_COND_SIG) + { + int res; + + if (cond->sig == _PTHREAD_COND_SIG_init) + { + _pthread_cond_init(cond, NULL); + res = ESUCCESS; + } else + res = EINVAL; /* Not a condition variable */ + UNLOCK(cond->lock); + return (res); + } + else if ((sem = cond->sem) == SEMAPHORE_NULL) + { + /* Avoid kernel call since there are no waiters... */ + UNLOCK(cond->lock); + return (ESUCCESS); + } + cond->sigspending++; + UNLOCK(cond->lock); + + PTHREAD_MACH_CALL(semaphore_signal_all(sem), kern_res); + + LOCK(cond->lock); + cond->sigspending--; + if (cond->waiters == 0 && cond->sigspending == 0) + { + cond->sem = SEMAPHORE_NULL; + restore_sem_to_pool(sem); + } + UNLOCK(cond->lock); + if (kern_res != KERN_SUCCESS) + return (EINVAL); + return (ESUCCESS); } /* @@ -116,48 +172,63 @@ pthread_cond_broadcast(pthread_cond_t *cond) int pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) { - kern_return_t kern_res; - if (cond->sig == _PTHREAD_COND_SIG_init) { - int res; - if ((res = pthread_cond_init(cond, NULL)) != 0) { - return (res); - } - } - if (cond->sig != _PTHREAD_COND_SIG) { - return (EINVAL); /* Not a condition variable */ - } - LOCK(cond->lock); - if (cond->sem == MACH_PORT_NULL) { - /* Avoid kernel call since there are not enough waiters... */ - UNLOCK(cond->lock); - return (ESUCCESS); - } - cond->sigspending++; - UNLOCK(cond->lock); - if (thread == (pthread_t)NULL) { - kern_res = semaphore_signal_thread(cond->sem, MACH_PORT_NULL); - if (kern_res == KERN_INVALID_ARGUMENT) { - PTHREAD_MACH_CALL(semaphore_signal(cond->sem), kern_res); - } else if (kern_res == KERN_NOT_WAITING) { - kern_res = KERN_SUCCESS; + kern_return_t kern_res; + semaphore_t sem; + int sig = cond->sig; + + /* to provide backwards compat for apps using united condtn vars */ + if((sig != _PTHREAD_COND_SIG) && (sig !=_PTHREAD_COND_SIG_init)) + return(EINVAL); + + LOCK(cond->lock); + if (cond->sig != _PTHREAD_COND_SIG) + { + int ret; + + if (cond->sig == _PTHREAD_COND_SIG_init) + { + _pthread_cond_init(cond, NULL); + ret = ESUCCESS; + } + else + ret = EINVAL; /* Not a condition variable */ + UNLOCK(cond->lock); + return (ret); + } + else if ((sem = cond->sem) == SEMAPHORE_NULL) + { + /* Avoid kernel call since there are not enough waiters... */ + UNLOCK(cond->lock); + return (ESUCCESS); } - } else if (thread->sig == _PTHREAD_SIG) { - PTHREAD_MACH_CALL(semaphore_signal_thread( - cond->sem, pthread_mach_thread_np(thread)), kern_res); - } else { - kern_res = KERN_FAILURE; - } - LOCK(cond->lock); - cond->sigspending--; - if (cond->waiters == 0 && cond->sigspending == 0) { - restore_sem_to_pool(cond->sem); - cond->sem = MACH_PORT_NULL; - } - UNLOCK(cond->lock); - if (kern_res != KERN_SUCCESS) { - return (EINVAL); - } - return (ESUCCESS); + cond->sigspending++; + UNLOCK(cond->lock); + + if (thread == (pthread_t)NULL) + { + kern_res = semaphore_signal_thread(sem, THREAD_NULL); + if (kern_res == KERN_NOT_WAITING) + kern_res = KERN_SUCCESS; + } + else if (thread->sig == _PTHREAD_SIG) + { + PTHREAD_MACH_CALL(semaphore_signal_thread( + sem, pthread_mach_thread_np(thread)), kern_res); + } + else + kern_res = KERN_FAILURE; + + LOCK(cond->lock); + cond->sigspending--; + if (cond->waiters == 0 && cond->sigspending == 0) + { + cond->sem = SEMAPHORE_NULL; + restore_sem_to_pool(sem); + } + UNLOCK(cond->lock); + if (kern_res != KERN_SUCCESS) + return (EINVAL); + return (ESUCCESS); } /* @@ -166,7 +237,7 @@ pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread) int pthread_cond_signal(pthread_cond_t *cond) { - return pthread_cond_signal_thread_np(cond, NULL); + return pthread_cond_signal_thread_np(cond, NULL); } /* @@ -186,15 +257,15 @@ _pthread_cond_add(pthread_cond_t *cond, pthread_mutex_t *mutex) cond->prev = (pthread_cond_t *)NULL; mutex->busy = cond; UNLOCK(mutex->lock); - if (cond->sem == MACH_PORT_NULL) { + if (cond->sem == SEMAPHORE_NULL) cond->sem = new_sem_from_pool(); - } } static void _pthread_cond_remove(pthread_cond_t *cond, pthread_mutex_t *mutex) { pthread_cond_t *n, *p; + LOCK(mutex->lock); if ((n = cond->next) != (pthread_cond_t *)NULL) { @@ -203,14 +274,16 @@ _pthread_cond_remove(pthread_cond_t *cond, pthread_mutex_t *mutex) if ((p = cond->prev) != (pthread_cond_t *)NULL) { p->next = cond->next; - } else + } + else { /* This is the first in the list */ mutex->busy = n; } UNLOCK(mutex->lock); - if (cond->sigspending == 0) { - restore_sem_to_pool(cond->sem); - cond->sem = MACH_PORT_NULL; + if (cond->sigspending == 0) + { + restore_sem_to_pool(cond->sem); + cond->sem = SEMAPHORE_NULL; } } @@ -225,88 +298,120 @@ _pthread_cond_wait(pthread_cond_t *cond, const struct timespec *abstime, int isRelative) { - int res; - kern_return_t kern_res; - pthread_mutex_t *busy; - mach_timespec_t then; - if (cond->sig == _PTHREAD_COND_SIG_init) { - if ((res = pthread_cond_init(cond, NULL)) != 0) { - return (res); - } - } - if (cond->sig != _PTHREAD_COND_SIG) { - /* Not a condition variable */ - return (EINVAL); - } - - if (abstime) { - if (isRelative == 0) { - struct timespec now; - struct timeval tv; - gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, &now); - - /* Compute relative time to sleep */ - then.tv_nsec = abstime->tv_nsec - now.tv_nsec; - then.tv_sec = abstime->tv_sec - now.tv_sec; - if (then.tv_nsec < 0) { - then.tv_nsec += NSEC_PER_SEC; - then.tv_sec--; - } - if (((int)then.tv_sec < 0) || - ((then.tv_sec == 0) && (then.tv_nsec == 0))) { - return ETIMEDOUT; - } - } else { - then.tv_sec = abstime->tv_sec; - then.tv_nsec = abstime->tv_nsec; - } - if (then.tv_nsec >= NSEC_PER_SEC) { - return EINVAL; - } - } - LOCK(cond->lock); - busy = cond->busy; - if ((busy != (pthread_mutex_t *)NULL) && (busy != mutex)) { - /* Must always specify the same mutex! */ - UNLOCK(cond->lock); - return (EINVAL); - } - cond->waiters++; - if (cond->waiters == 1) { - _pthread_cond_add(cond, mutex); - cond->busy = mutex; - } - UNLOCK(cond->lock); - LOCK(mutex->lock); - if (mutex->sem == MACH_PORT_NULL) { - mutex->sem = new_sem_from_pool(); - } - mutex->cond_lock = 1; - UNLOCK(mutex->lock); - if (abstime) { - kern_res = semaphore_timedwait_signal(cond->sem, mutex->sem, then); - } else { - PTHREAD_MACH_CALL(semaphore_wait_signal(cond->sem, mutex->sem), kern_res); - } - LOCK(cond->lock); - cond->waiters--; - if (cond->waiters == 0) { - _pthread_cond_remove(cond, mutex); - cond->busy = (pthread_mutex_t *)NULL; - } - UNLOCK(cond->lock); - if ((res = pthread_mutex_lock(mutex)) != ESUCCESS) { - return (res); - } - /* KERN_ABORTED can be treated as a spurious wakeup */ - if ((kern_res == KERN_SUCCESS) || (kern_res == KERN_ABORTED)) { - return (ESUCCESS); - } else if (kern_res == KERN_OPERATION_TIMED_OUT) { - return (ETIMEDOUT); - } else { - return (EINVAL); - } + int res; + kern_return_t kern_res; + pthread_mutex_t *busy; + mach_timespec_t then; + int sig = cond->sig; + + /* to provide backwards compat for apps using united condtn vars */ + if((sig != _PTHREAD_COND_SIG) && (sig !=_PTHREAD_COND_SIG_init)) + return(EINVAL); + LOCK(cond->lock); + if (cond->sig != _PTHREAD_COND_SIG) + { + if (cond->sig != _PTHREAD_COND_SIG_init) + { + UNLOCK(cond->lock); + return (EINVAL); /* Not a condition variable */ + } + _pthread_cond_init(cond, NULL); + } + + if (abstime) + { + if (isRelative == 0) + { + struct timespec now; + struct timeval tv; + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, &now); + + /* Compute relative time to sleep */ + then.tv_nsec = abstime->tv_nsec - now.tv_nsec; + then.tv_sec = abstime->tv_sec - now.tv_sec; + if (then.tv_nsec < 0) + { + then.tv_nsec += NSEC_PER_SEC; + then.tv_sec--; + } + if (((int)then.tv_sec < 0) || + ((then.tv_sec == 0) && (then.tv_nsec == 0))) + { + UNLOCK(cond->lock); + return ETIMEDOUT; + } + } + else + { + then.tv_sec = abstime->tv_sec; + then.tv_nsec = abstime->tv_nsec; + } + if (then.tv_nsec >= NSEC_PER_SEC) + { + UNLOCK(cond->lock); + return EINVAL; + } + } + + if (++cond->waiters == 1) + { + _pthread_cond_add(cond, mutex); + cond->busy = mutex; + } + else if ((busy = cond->busy) != mutex) + { + /* Must always specify the same mutex! */ + cond->waiters--; + UNLOCK(cond->lock); + return (EINVAL); + } + UNLOCK(cond->lock); + +#if defined(DEBUG) + _pthread_mutex_remove(mutex, pthread_self()); +#endif + LOCK(mutex->lock); + if (--mutex->lock_count == 0) + { + if (mutex->sem == SEMAPHORE_NULL) + mutex->sem = new_sem_from_pool(); + mutex->owner = _PTHREAD_MUTEX_OWNER_SWITCHING; + UNLOCK(mutex->lock); + + if (abstime) { + kern_res = semaphore_timedwait_signal(cond->sem, mutex->sem, then); + } else { + PTHREAD_MACH_CALL(semaphore_wait_signal(cond->sem, mutex->sem), kern_res); + } + } + else + { + UNLOCK(mutex->lock); + if (abstime) { + kern_res = semaphore_timedwait(cond->sem, then); + } else { + PTHREAD_MACH_CALL(semaphore_wait(cond->sem), kern_res); + } + } + + LOCK(cond->lock); + cond->waiters--; + if (cond->waiters == 0) + { + _pthread_cond_remove(cond, mutex); + cond->busy = (pthread_mutex_t *)NULL; + } + UNLOCK(cond->lock); + if ((res = pthread_mutex_lock(mutex)) != ESUCCESS) + return (res); + + /* KERN_ABORTED can be treated as a spurious wakeup */ + if ((kern_res == KERN_SUCCESS) || (kern_res == KERN_ABORTED)) + return (ESUCCESS); + else if (kern_res == KERN_OPERATION_TIMED_OUT) + return (ETIMEDOUT); + return (EINVAL); } int diff --git a/pthreads/pthread_impl.h b/pthreads/pthread_impl.h index ef83dee..f5bc332 100644 --- a/pthreads/pthread_impl.h +++ b/pthreads/pthread_impl.h @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 _PTHREAD_IMPL_H_ #define _PTHREAD_IMPL_H_ /* diff --git a/pthreads/pthread_internals.h b/pthreads/pthread_internals.h index 6a26786..1a7458d 100644 --- a/pthreads/pthread_internals.h +++ b/pthreads/pthread_internals.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -32,18 +56,11 @@ #include -#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* For generic MACH support */ #ifndef __POSIX_LIB__ @@ -51,10 +68,13 @@ #endif #include "posix_sched.h" /* For POSIX scheduling policy & parameter */ +#include /* For POSIX scheduling policy & parameter */ #include "pthread_machdep.h" /* Machine-dependent definitions. */ +#include "pthread_spinlock.h" /* spinlock definitions. */ -extern kern_return_t syscall_thread_switch(mach_port_name_t, int, mach_msg_timeout_t); - +LIST_HEAD(__pthread_list, _pthread); +extern struct __pthread_list __pthread_head; /* head of list of open files */ +extern pthread_lock_t _pthread_list_lock; /* * Compiled-in limits */ @@ -69,9 +89,12 @@ typedef struct _pthread long sig; /* Unique signature for this structure */ struct _pthread_handler_rec *cleanup_stack; pthread_lock_t lock; /* Used for internal mutex on structure */ - int detached; - int inherit; - int policy; + u_int32_t detached:8, + inherit:8, + policy:8, + pad:8; + size_t guardsize; /* size in bytes to guard stack overflow */ + int pad0; struct sched_param param; struct _pthread_mutex *mutexes; struct _pthread *joiner; @@ -88,9 +111,15 @@ typedef struct _pthread 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 */ void *cthread_self; /* cthread_self() if somebody calls cthread_set_self() */ - boolean_t freeStackOnExit;/* Should we free the stack when we're done? */ + boolean_t freeStackOnExit; /* Should we free the stack when we're done? */ + LIST_ENTRY(_pthread) plist; } *pthread_t; +/* + * This will cause a compile-time failure if someone moved the tsd field + * and we need to change _PTHREAD_TSD_OFFSET in pthread_machdep.h + */ +typedef char _need_to_change_PTHREAD_TSD_OFFSET[(_PTHREAD_TSD_OFFSET == offsetof(struct _pthread, tsd[0])) ? 0 : -1] ; /* * Thread attributes @@ -99,9 +128,12 @@ typedef struct { long sig; /* Unique signature for this structure */ pthread_lock_t lock; /* Used for internal mutex on structure */ - int detached; - int inherit; - int policy; + u_int32_t detached:8, + inherit:8, + policy:8, + reserved1:8; + size_t guardsize; /* size in bytes to guard stack overflow */ + int reserved2; 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) */ @@ -127,19 +159,18 @@ typedef struct _pthread_mutex { long sig; /* Unique signature for this structure */ pthread_lock_t lock; /* Used for internal mutex on structure */ - int waiters:30, /* Count of threads waiting for this mutex */ - def:1, - cond_lock:1; /* Is there a condition locking me? */ + u_int32_t waiters; /* Count of threads waiting for this mutex */ pthread_t owner; /* Which thread has this mutex locked */ - mach_port_t sem; /* Semaphore used for waiting */ + semaphore_t sem; /* Semaphore used for waiting */ u_int32_t protocol:2, /* protocol */ type:2, /* mutex type */ rfu:12, 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 */ - int prioceiling; - int priority; /* Priority to restore when mutex unlocked */ + int16_t prioceiling; + int16_t priority; /* Priority to restore when mutex unlocked */ + semaphore_t order; } pthread_mutex_t; /* @@ -158,10 +189,10 @@ typedef struct _pthread_cond { long sig; /* Unique signature for this structure */ pthread_lock_t lock; /* Used for internal mutex on structure */ - mach_port_t sem; /* Kernel semaphore */ + semaphore_t sem; /* Kernel semaphore */ struct _pthread_cond *next, *prev; /* List of condition variables using mutex */ struct _pthread_mutex *busy; /* mutex associated with variable */ - int waiters:16, /* Number of threads waiting */ + u_int32_t waiters:16, /* Number of threads waiting */ sigspending:16; /* Number of outstanding signals */ } pthread_cond_t; @@ -217,41 +248,19 @@ typedef struct { #define _PTHREAD_CREATE_PARENT 4 #define _PTHREAD_EXITED 8 +#if defined(DEBUG) +#define _PTHREAD_MUTEX_OWNER_SELF pthread_self() +#else +#define _PTHREAD_MUTEX_OWNER_SELF (pthread_t)0x12141968 +#endif +#define _PTHREAD_MUTEX_OWNER_SWITCHING (pthread_t)(~0) + #define _PTHREAD_CANCEL_STATE_MASK 0xFE #define _PTHREAD_CANCEL_TYPE_MASK 0xFD #define _PTHREAD_CANCEL_PENDING 0x10 /* pthread_cancel() has been called for this thread */ extern boolean_t swtch_pri(int); -/* Number of times to spin when the lock is unavailable and we are on a - multiprocessor. On a uniprocessor we yield the processor immediately. */ -#define MP_SPIN_TRIES 1000 -extern int _spin_tries; -extern int __is_threaded; -extern int _cpu_has_altivec; - -/* Internal mutex locks for data structures */ -#define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v))) -#define LOCK(v) \ -do { \ - if (__is_threaded) { \ - int tries = _spin_tries; \ - \ - while (!_spin_lock_try((pthread_lock_t *)&(v))) { \ - if (tries-- > 0) \ - continue; \ - \ - syscall_thread_switch(THREAD_NULL, SWITCH_OPTION_DEPRESS, 1); \ - tries = _spin_tries; \ - } \ - } \ -} while (0) -#define UNLOCK(v) \ -do { \ - if (__is_threaded) \ - _spin_unlock((pthread_lock_t *)&(v)); \ -} while (0) - #ifndef ESUCCESS #define ESUCCESS 0 #endif @@ -265,9 +274,6 @@ do { \ /* Functions defined in machine-dependent files. */ extern vm_address_t _sp(void); extern vm_address_t _adjust_sp(vm_address_t sp); -extern void _spin_lock(pthread_lock_t *lockp); -extern int _spin_lock_try(pthread_lock_t *lockp); -extern void _spin_unlock(pthread_lock_t *lockp); extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), void *sp, int suspended, int needresume); extern void _pthread_tsd_cleanup(pthread_t self); diff --git a/pthreads/pthread_join.3 b/pthreads/pthread_join.3 index 9fcbfab..ef9ddf8 100644 --- a/pthreads/pthread_join.3 +++ b/pthreads/pthread_join.3 @@ -68,8 +68,6 @@ If the thread calling .Fn pthread_join is cancelled, then the target thread is not detached. .Pp -A thread that has exited but remains unjoined counts against -[_POSIX_THREAD_THREADS_MAX]. .Sh RETURN VALUES If successful, the .Fn pthread_join diff --git a/pthreads/pthread_machdep.h b/pthreads/pthread_machdep.h index 57a3f24..f90bbb8 100644 --- a/pthreads/pthread_machdep.h +++ b/pthreads/pthread_machdep.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -24,9 +48,15 @@ /* Machine-dependent definitions for pthread internals. */ +#ifndef _POSIX_PTHREAD_MACHDEP_H +#define _POSIX_PTHREAD_MACHDEP_H + +#define _PTHREAD_TSD_OFFSET 0x48 +#ifndef __ASSEMBLER__ typedef long pthread_lock_t; +#endif #define LOCK_INIT(l) ((l) = 0) #define LOCK_INITIALIZER 0 -#undef STACK_GROWS_UP +#endif /* _POSIX_PTHREAD_MACHDEP_H */ diff --git a/pthreads/pthread_mutex.c b/pthreads/pthread_mutex.c index c82a692..fce2d5c 100644 --- a/pthreads/pthread_mutex.c +++ b/pthreads/pthread_mutex.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -36,49 +60,65 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex) { - if (mutex->sig != _PTHREAD_MUTEX_SIG) - return (EINVAL); - if ((mutex->owner != (pthread_t)NULL) || - (mutex->busy != (pthread_cond_t *)NULL)) - return (EBUSY); - mutex->sig = _PTHREAD_NO_SIG; + int res; + + LOCK(mutex->lock); + if (mutex->sig == _PTHREAD_MUTEX_SIG) + { + if (mutex->owner == (pthread_t)NULL && + mutex->busy == (pthread_cond_t *)NULL) + { + mutex->sig = _PTHREAD_NO_SIG; + res = ESUCCESS; + } + else + res = EBUSY; + } + else + res = EINVAL; + UNLOCK(mutex->lock); + return (res); +} + +/* + * Initialize a mutex variable, possibly with additional attributes. + */ +static int +_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + if (attr) + { + if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) + return (EINVAL); + mutex->prioceiling = attr->prioceiling; + mutex->protocol = attr->protocol; + mutex->type = attr->type; + } else { + mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; + mutex->protocol = _PTHREAD_DEFAULT_PROTOCOL; + mutex->type = PTHREAD_MUTEX_DEFAULT; + } + 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 = _PTHREAD_MUTEX_SIG; return (ESUCCESS); } /* * Initialize a mutex variable, possibly with additional attributes. + * Public interface - so don't trust the lock - initialize it first. */ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - LOCK_INIT(mutex->lock); - mutex->sig = _PTHREAD_MUTEX_SIG; - if (attr) - { - if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) - return (EINVAL); - mutex->prioceiling = attr->prioceiling; - mutex->protocol = attr->protocol; - mutex->type = attr->type; - if ((mutex->type == PTHREAD_MUTEX_DEFAULT) || (mutex->type == PTHREAD_MUTEX_NORMAL)) - mutex->def = 1; - else - mutex->def = 0; - } else { - mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; - mutex->protocol = _PTHREAD_DEFAULT_PROTOCOL; - mutex->type = PTHREAD_MUTEX_DEFAULT; - mutex->def = 1; - } - 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->cond_lock = 0; - mutex->sem = MACH_PORT_NULL; - return (ESUCCESS); + LOCK_INIT(mutex->lock); + return (_pthread_mutex_init(mutex, attr)); } /* @@ -89,18 +129,19 @@ static void _pthread_mutex_add(pthread_mutex_t *mutex, pthread_t self) { pthread_mutex_t *m; - if (self != (pthread_t)0) { - if ((m = self->mutexes) != (pthread_mutex_t *)NULL) + if (self != (pthread_t)0) + { + if ((m = self->mutexes) != (pthread_mutex_t *)NULL) { /* Add to list */ - m->prev = mutex; + m->prev = mutex; } - mutex->next = m; - mutex->prev = (pthread_mutex_t *)NULL; - self->mutexes = mutex; + mutex->next = m; + mutex->prev = (pthread_mutex_t *)NULL; + self->mutexes = mutex; } } -static void +__private_extern__ void _pthread_mutex_remove(pthread_mutex_t *mutex, pthread_t self) { pthread_mutex_t *n, *prev; @@ -113,9 +154,9 @@ _pthread_mutex_remove(pthread_mutex_t *mutex, pthread_t self) prev->next = mutex->next; } else { /* This is the first in the list */ - if (self != (pthread_t)0) { - self->mutexes = n; - } + if (self != (pthread_t)0) { + self->mutexes = n; + } } } #endif @@ -127,74 +168,100 @@ _pthread_mutex_remove(pthread_mutex_t *mutex, pthread_t self) int pthread_mutex_lock(pthread_mutex_t *mutex) { - kern_return_t kern_res; - pthread_t self; - int slowpath; - - if (mutex->sig == _PTHREAD_MUTEX_SIG_init) - { - int res; - if (res = pthread_mutex_init(mutex, NULL)) - return (res); - } - if (mutex->sig != _PTHREAD_MUTEX_SIG) - return (EINVAL); /* Not a mutex variable */ - -#if !defined(DEBUG) - if (mutex->def) { - slowpath = 0; - self = (pthread_t)0x12141968; - } else -#endif /* DEBUG */ + kern_return_t kern_res; + pthread_t self; + int sig = mutex->sig; + + /* To provide backwards compat for apps using mutex incorrectly */ + if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) + return(EINVAL); + LOCK(mutex->lock); + if (mutex->sig != _PTHREAD_MUTEX_SIG) { - slowpath = 1; - self = pthread_self(); - } - - LOCK(mutex->lock); - - if (mutex->waiters || (mutex->owner != (pthread_t)NULL)) + if (mutex->sig != _PTHREAD_MUTEX_SIG_init) + { + UNLOCK(mutex->lock); + return (EINVAL); + } + _pthread_mutex_init(mutex, NULL); + self = _PTHREAD_MUTEX_OWNER_SELF; + } + else if (mutex->type != PTHREAD_MUTEX_NORMAL) { - if(slowpath && (mutex->owner == self)) { - if(mutex->type == PTHREAD_MUTEX_ERRORCHECK ) { - UNLOCK(mutex->lock); - return(EDEADLK); - } else if (mutex->type == PTHREAD_MUTEX_RECURSIVE ) { - if (mutex->lock_count >= USHRT_MAX){ - UNLOCK(mutex->lock); - return(EAGAIN); - } - mutex->lock_count++; - UNLOCK(mutex->lock); - return(ESUCCESS); - } - } - mutex->waiters++; - if (mutex->sem == MACH_PORT_NULL) { - mutex->sem = new_sem_from_pool(); + self = pthread_self(); + if (mutex->owner == self) + { + int res; + + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) + { + if (mutex->lock_count < USHRT_MAX) + { + mutex->lock_count++; + res = ESUCCESS; + } else + res = EAGAIN; + } else /* PTHREAD_MUTEX_ERRORCHECK */ + res = EDEADLK; + UNLOCK(mutex->lock); + return (res); } - UNLOCK(mutex->lock); - do { - PTHREAD_MACH_CALL(semaphore_wait(mutex->sem), kern_res); - } while (kern_res == KERN_ABORTED); - LOCK(mutex->lock); - mutex->waiters--; - if (mutex->waiters == 0) { - restore_sem_to_pool(mutex->sem); - mutex->sem = MACH_PORT_NULL; + } else + self = _PTHREAD_MUTEX_OWNER_SELF; + + if (mutex->owner != (pthread_t)NULL) { + if (mutex->waiters || mutex->owner != _PTHREAD_MUTEX_OWNER_SWITCHING) + { + semaphore_t sem, order; + + if (++mutex->waiters == 1) + { + mutex->sem = sem = new_sem_from_pool(); + mutex->order = order = new_sem_from_pool(); + } + else + { + sem = mutex->sem; + order = mutex->order; + do { + PTHREAD_MACH_CALL(semaphore_wait(order), kern_res); + } while (kern_res == KERN_ABORTED); + } + UNLOCK(mutex->lock); + + PTHREAD_MACH_CALL(semaphore_wait_signal(sem, order), kern_res); + while (kern_res == KERN_ABORTED) + { + PTHREAD_MACH_CALL(semaphore_wait(sem), kern_res); + } + + LOCK(mutex->lock); + if (--mutex->waiters == 0) + { + PTHREAD_MACH_CALL(semaphore_wait(order), kern_res); + mutex->sem = mutex->order = SEMAPHORE_NULL; + restore_sem_to_pool(order); + restore_sem_to_pool(sem); + } + } + else if (mutex->owner == _PTHREAD_MUTEX_OWNER_SWITCHING) + { + semaphore_t sem = mutex->sem; + do { + PTHREAD_MACH_CALL(semaphore_wait(sem), kern_res); + } while (kern_res == KERN_ABORTED); + mutex->sem = SEMAPHORE_NULL; + restore_sem_to_pool(sem); } - if (mutex->cond_lock) { - mutex->cond_lock = 0; - } - } -#if defined(DEBUG) - _pthread_mutex_add(mutex, self); + } + + mutex->lock_count = 1; + mutex->owner = self; +#if defined(DEBUG) + _pthread_mutex_add(mutex, self); #endif - mutex->owner = self; - if (slowpath && (mutex->type == PTHREAD_MUTEX_RECURSIVE)) - mutex->lock_count = 1; - UNLOCK(mutex->lock); - return (ESUCCESS); + UNLOCK(mutex->lock); + return (ESUCCESS); } /* @@ -203,65 +270,68 @@ pthread_mutex_lock(pthread_mutex_t *mutex) int pthread_mutex_trylock(pthread_mutex_t *mutex) { - kern_return_t kern_res; - pthread_t self; - int slowpath; - - if (mutex->sig == _PTHREAD_MUTEX_SIG_init) - { - int res; - if (res = pthread_mutex_init(mutex, NULL)) - return (res); - } - if (mutex->sig != _PTHREAD_MUTEX_SIG) - return (EINVAL); /* Not a mutex variable */ - -#if !defined(DEBUG) - if (mutex->def) { - slowpath = 0; - self = (pthread_t)0x12141968; - } else -#endif /* DEBUG */ + kern_return_t kern_res; + pthread_t self; + + LOCK(mutex->lock); + if (mutex->sig != _PTHREAD_MUTEX_SIG) { - slowpath = 1; - self = pthread_self(); + if (mutex->sig != _PTHREAD_MUTEX_SIG_init) + { + UNLOCK(mutex->lock); + return (EINVAL); + } + _pthread_mutex_init(mutex, NULL); + self = _PTHREAD_MUTEX_OWNER_SELF; } + else if (mutex->type != PTHREAD_MUTEX_NORMAL) + { + self = pthread_self(); + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) + { + if (mutex->owner == self) + { + int res; + + if (mutex->lock_count < USHRT_MAX) + { + mutex->lock_count++; + res = ESUCCESS; + } else + res = EAGAIN; + UNLOCK(mutex->lock); + return (res); + } + } + } else + self = _PTHREAD_MUTEX_OWNER_SELF; - if (!TRY_LOCK(mutex->lock)) { - return (EBUSY); - } - - if(slowpath && (mutex->owner == self) && (mutex->type == PTHREAD_MUTEX_RECURSIVE )) { - if (mutex->lock_count >= USHRT_MAX) { - UNLOCK(mutex->lock); - return(EAGAIN); + if (mutex->owner != (pthread_t)NULL) + { + if (mutex->waiters || mutex->owner != _PTHREAD_MUTEX_OWNER_SWITCHING) + { + UNLOCK(mutex->lock); + return (EBUSY); } - mutex->lock_count++; - UNLOCK(mutex->lock); - return(ESUCCESS); - } - - if (mutex->waiters || - ((mutex->owner != (pthread_t)NULL) && (mutex->cond_lock == 0))) - { - UNLOCK(mutex->lock); - return (EBUSY); - } else { + else if (mutex->owner == _PTHREAD_MUTEX_OWNER_SWITCHING) + { + semaphore_t sem = mutex->sem; + + do { + PTHREAD_MACH_CALL(semaphore_wait(sem), kern_res); + } while (kern_res == KERN_ABORTED); + restore_sem_to_pool(sem); + mutex->sem = SEMAPHORE_NULL; + } + } + + mutex->lock_count = 1; + mutex->owner = self; #if defined(DEBUG) - _pthread_mutex_add(mutex, self); + _pthread_mutex_add(mutex, self); #endif - mutex->owner = (pthread_t)self; - if (mutex->cond_lock) { - PTHREAD_MACH_CALL(semaphore_wait(mutex->sem), kern_res); - mutex->cond_lock = 0; - restore_sem_to_pool(mutex->sem); - mutex->sem = MACH_PORT_NULL; - } - if (slowpath && (mutex->type == PTHREAD_MUTEX_RECURSIVE)) - mutex->lock_count = 1; - UNLOCK(mutex->lock); - return (ESUCCESS); - } + UNLOCK(mutex->lock); + return (ESUCCESS); } /* @@ -271,67 +341,63 @@ pthread_mutex_trylock(pthread_mutex_t *mutex) int pthread_mutex_unlock(pthread_mutex_t *mutex) { - kern_return_t kern_res; - int waiters; - pthread_t self; - int slowpath; - - if (mutex->sig == _PTHREAD_MUTEX_SIG_init) - { - int res; - if (res = pthread_mutex_init(mutex, NULL)) - return (res); - } - if (mutex->sig != _PTHREAD_MUTEX_SIG) - return (EINVAL); /* Not a mutex variable */ + kern_return_t kern_res; + int waiters; + int sig = mutex->sig; -#if !defined(DEBUG) - if (mutex->def) { - slowpath = 0; - self = (pthread_t)0x12141968; - } else -#endif /* DEBUG */ + /* To provide backwards compat for apps using mutex incorrectly */ + + if ((sig != _PTHREAD_MUTEX_SIG) && (sig != _PTHREAD_MUTEX_SIG_init)) + return(EINVAL); + LOCK(mutex->lock); + if (mutex->sig != _PTHREAD_MUTEX_SIG) { - slowpath = 1; - self = pthread_self(); - } - - LOCK(mutex->lock); + if (mutex->sig != _PTHREAD_MUTEX_SIG_init) + { + UNLOCK(mutex->lock); + return (EINVAL); /* Not a mutex variable */ + } + _pthread_mutex_init(mutex, NULL); + } else -#if defined(DEBUG) - if (mutex->owner != self) -#else - if (slowpath - && ((mutex->type == PTHREAD_MUTEX_ERRORCHECK ) - || (mutex->type == PTHREAD_MUTEX_RECURSIVE )) - && (mutex->owner != self)) -#endif /* DEBUG */ +#if !defined(DEBUG) + if (mutex->type != PTHREAD_MUTEX_NORMAL) +#endif { - UNLOCK(mutex->lock); + pthread_t self = pthread_self(); + if (mutex->owner != self) + { #if defined(DEBUG) - abort(); + abort(); #endif - return(EPERM); - } - - if (slowpath && (mutex->type == PTHREAD_MUTEX_RECURSIVE) && --mutex->lock_count) { - UNLOCK(mutex->lock); - return (ESUCCESS); - - } else { + UNLOCK(mutex->lock); + return EPERM; + } else if (mutex->type == PTHREAD_MUTEX_RECURSIVE && + --mutex->lock_count) + { + UNLOCK(mutex->lock); + return ESUCCESS; + } + } + + mutex->lock_count = 0; #if defined(DEBUG) - _pthread_mutex_remove(mutex, mutex->owner); + _pthread_mutex_remove(mutex, mutex->owner); #endif /* DEBUG */ - waiters = mutex->waiters; - mutex->owner = (pthread_t)NULL; + + waiters = mutex->waiters; + if (waiters) + { + mutex->owner = _PTHREAD_MUTEX_OWNER_SWITCHING; UNLOCK(mutex->lock); - if (waiters) - { - PTHREAD_MACH_CALL(semaphore_signal(mutex->sem), kern_res); - } - return (ESUCCESS); - - } + PTHREAD_MACH_CALL(semaphore_signal(mutex->sem), kern_res); + } + else + { + mutex->owner = (pthread_t)NULL; + UNLOCK(mutex->lock); + } + return (ESUCCESS); } /* @@ -342,14 +408,17 @@ int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling) { + int res; + + LOCK(mutex->lock); if (mutex->sig == _PTHREAD_MUTEX_SIG) { *prioceiling = mutex->prioceiling; - return (ESUCCESS); + res = ESUCCESS; } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } + res = EINVAL; /* Not an initialized 'attribute' structure */ + UNLOCK(mutex->lock); + return (res); } /* @@ -361,6 +430,9 @@ pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_prioceiling) { + int res; + + LOCK(mutex->lock); if (mutex->sig == _PTHREAD_MUTEX_SIG) { if ((prioceiling >= -999) || @@ -368,15 +440,13 @@ pthread_mutex_setprioceiling(pthread_mutex_t *mutex, { *old_prioceiling = mutex->prioceiling; mutex->prioceiling = prioceiling; - return (ESUCCESS); + res = ESUCCESS; } else - { - return (EINVAL); /* Invalid parameter */ - } + res = EINVAL; /* Invalid parameter */ } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } + res = EINVAL; /* Not an initialized 'attribute' structure */ + UNLOCK(mutex->lock); + return (res); } /* diff --git a/pthreads/pthread_mutexattr.3 b/pthreads/pthread_mutexattr.3 index 7588739..e8aeba9 100644 --- a/pthreads/pthread_mutexattr.3 +++ b/pthreads/pthread_mutexattr.3 @@ -1,3 +1,30 @@ +.\" $NetBSD: pthread_mutexattr.3,v 1.3 2003/07/04 08:36:06 wiz Exp $ +.\" +.\" Copyright (c) 2002 The NetBSD Foundation, 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 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. +.\" .\" Copyright (C) 2000 Jason Evans . .\" All rights reserved. .\" @@ -25,8 +52,8 @@ .\" 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_r/man/pthread_mutexattr.3,v 1.2.2.5 2001/08/17 15:42:52 ru Exp $ -.Dd May 1, 2000 +.\" $FreeBSD: src/lib/libpthread/man/pthread_mutexattr.3,v 1.8 2002/09/16 19:29:29 mini Exp $ +.Dd January 30, 2003 .Dt PTHREAD_MUTEXATTR 3 .Os .Sh NAME @@ -76,6 +103,67 @@ function destroys .Fa attr . .Pp The +.Fn pthread_mutexattr_settype +functions set the mutex type value of the attribute. Valid mutex types are: +.Dv PTHREAD_MUTEX_NORMAL , +.Dv PTHREAD_MUTEX_ERRORCHECK , +.Dv PTHREAD_MUTEX_RECURSIVE , +and +.Dv PTHREAD_MUTEX_DEFAULT . +The default mutex type for +.Fn pthread_mutexaddr_init +is +.Dv PTHREAD_MUTEX_DEFAULT . +.Pp +.Dv PTHREAD_MUXEX_NORMAL +mutexes do not check for usage errors. +.Dv PTHREAD_MUTEX_NORMAL +mutexes will deadlock if reentered, and result in undefined behavior if a +locked mutex is unlocked by another thread. Attempts to unlock an already +unlocked +.Dv PTHREAD_MUTEX_NORMAL +mutex will result in undefined behavior. +.Pp +.Dv PTHREAD_MUTEX_ERRORCHECK +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 +.Dv PTHREAD_MUTEX_ERRORCHECK +mutex that is locked by another thread, an error will be returned. If a +thread attemps to unlock a +.Dv PTHREAD_MUTEX_ERRORCHECK +thread that is unlocked, an error will be +returned. +.Pp +.Dv PTHREAD_MUTEX_RECURSIVE +mutexes allow recursive locking. +An attempt to relock a +.Dv PTHREAD_MUTEX_RECURSIVE +mutex that is already locked by the same thread succeeds. An equivalent +number of +.Xr pthread_mutex_unlock 3 +calls are needed before the mutex will wake another thread waiting on this +lock. If a thread attempts to unlock a +.Dv PTHREAD_MUTEX_RECURSIVE +mutex that is locked by another thread, an error will be returned. If a thread attemps to unlock a +.Dv PTHREAD_MUTEX_RECURSIVE +thread that is unlocked, an error will be returned. +.Pp +.Dv PTHREAD_MUTEX_DEFAULT +mutexes result in undefined behavior if reentered. +Unlocking a +.Dv PTHREAD_MUTEX_DEFAULT +mutex locked by another thread will result in undefined behavior. Attempts to unlock an already +unlocked +.Dv PTHREAD_MUTEX_DEFAULT +mutex will result in undefined behavior. +.Pp +.Fn pthread_mutexattr_gettype +functions copy the type value of the attribute to the location pointed to by the second parameter. +.Pp +The .Fn pthread_mutexattr_set* functions set the attribute that corresponds to each function name. .Pp @@ -85,7 +173,7 @@ functions copy the value of the attribute that corresponds to each function name to the location pointed to by the second function parameter. .Sh RETURN VALUES If successful, these functions return 0. -Otherwise, an error number is returned to indicacte the error. +Otherwise, an error number is returned to indicate the error. .Sh ERRORS .Fn pthread_mutexattr_init will fail if: diff --git a/pthreads/pthread_rwlock.c b/pthreads/pthread_rwlock.c index 978ed80..3ce5ef2 100644 --- a/pthreads/pthread_rwlock.c +++ b/pthreads/pthread_rwlock.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 Alex Nash * All rights reserved. diff --git a/pthreads/pthread_spinlock.h b/pthreads/pthread_spinlock.h new file mode 100644 index 0000000..808a417 --- /dev/null +++ b/pthreads/pthread_spinlock.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 Threads - IEEE 1003.1c + */ + +#ifndef _POSIX_PTHREAD_SPINLOCK_H +#define _POSIX_PTHREAD_SPINLOCK_H + +#include +#define __APPLE_API_PRIVATE +#include + +#ifndef __POSIX_LIB__ +#define __POSIX_LIB__ +#endif + +#include "pthread_machdep.h" /* Machine-dependent definitions. */ + +/* Number of times to spin when the lock is unavailable and we are on a + multiprocessor. On a uniprocessor we yield the processor immediately. */ +#define MP_SPIN_TRIES 1000 +extern int _spin_tries; +extern int __is_threaded; + +/* Internal mutex locks for data structures */ +#define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v))) + +/* _DO_SPINLOCK_LOCK() takes a (pthread_lock_t *) */ +#define _DO_SPINLOCK_LOCK(v) _spin_lock(v) + +/* _DO_SPINLOCK_UNLOCK() takes a (pthread_lock_t *) */ +#define _DO_SPINLOCK_UNLOCK(v) _spin_unlock(v) + +/* LOCK() takes a (pthread_lock_t) */ +#define LOCK(v) \ + do { \ + if (__is_threaded) { \ + _DO_SPINLOCK_LOCK((pthread_lock_t *)&(v)); \ + } \ + } while (0) + +/* UNLOCK() takes a (pthread_lock_t) */ +#define UNLOCK(v) \ + do { \ + if (__is_threaded) { \ + _DO_SPINLOCK_UNLOCK((pthread_lock_t *)&(v)); \ + } \ + } while (0) + +/* Prototypes. */ + +/* Functions defined in machine-dependent files. */ +extern void _spin_lock(pthread_lock_t *lockp); +extern int _spin_lock_try(pthread_lock_t *lockp); +extern void _spin_unlock(pthread_lock_t *lockp); + +#endif /* _POSIX_PTHREAD_SPINLOCK_H */ diff --git a/pthreads/pthread_tsd.c b/pthreads/pthread_tsd.c index f8cfb6b..3e90f37 100644 --- a/pthreads/pthread_tsd.c +++ b/pthreads/pthread_tsd.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 @@ -26,6 +50,7 @@ /* * POSIX Pthread Library * Thread Specific Data support + * NB: pthread_getspecific() is in a separate assembly file */ #include "pthread_internals.h" @@ -47,13 +72,14 @@ pthread_key_create(pthread_key_t *key, int res, i; LOCK(tds_lock); res = ENOMEM; /* No 'free' keys */ - for (i = 0; i < _POSIX_THREAD_KEYS_MAX; i++) + /* The first slot is reserved for pthread_self() */ + for (i = 1; i < _POSIX_THREAD_KEYS_MAX; i++) { if (_pthread_keys[i].created == FALSE) { _pthread_keys[i].created = TRUE; _pthread_keys[i].destructor = destructor; - *key = i+1; + *key = i; res = ESUCCESS; break; } @@ -70,11 +96,20 @@ pthread_key_delete(pthread_key_t key) { int res; LOCK(tds_lock); - if ((key >= 1) && (key <= _POSIX_THREAD_KEYS_MAX)) + /* The first slot is reserved for pthread_self() */ + if ((key > 0) && (key < _POSIX_THREAD_KEYS_MAX)) { - if (_pthread_keys[key-1].created) + if (_pthread_keys[key].created) { - _pthread_keys[key-1].created = FALSE; + struct _pthread * p; + + _pthread_keys[key].created = FALSE; + LOCK(_pthread_list_lock); + LIST_FOREACH(p, &__pthread_head, plist) { + /* It is an 32bit value no lock needed */ + p->tsd[key] = 0; + } + UNLOCK(_pthread_list_lock); res = ESUCCESS; } else { @@ -103,12 +138,13 @@ pthread_setspecific(pthread_key_t key, { int res; pthread_t self; - if ((key >= 1) && (key <= _POSIX_THREAD_KEYS_MAX)) + /* The first slot is reserved for pthread_self() */ + if ((key > 0) && (key < _POSIX_THREAD_KEYS_MAX)) { - if (_pthread_keys[key-1].created) + if (_pthread_keys[key].created) { self = pthread_self(); - self->tsd[key-1] = (void *) value; + self->tsd[key] = (void *) value; res = ESUCCESS; } else { @@ -121,27 +157,6 @@ pthread_setspecific(pthread_key_t key, return (res); } -/* - * Fetch the thread private value for a given key. - * This is potentially a very heavily-used operation so we do only - * a minimum of checks. - */ -void * -pthread_getspecific(pthread_key_t key) -{ - pthread_t self; - void *res; - if ((key >= 1) && (key <= _POSIX_THREAD_KEYS_MAX)) - { - self = pthread_self(); - res = self->tsd[key-1]; - } else - { /* Invalid key - no error, just NULL */ - res = (void *)NULL; - } - return (res); -} - /* * Clean up thread specific data as thread 'dies' */ @@ -152,7 +167,8 @@ _pthread_tsd_cleanup(pthread_t self) void *param; for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) { - for (i = 0; i < _POSIX_THREAD_KEYS_MAX; i++) + /* The first slot is reserved for pthread_self() */ + for (i = 1; i < _POSIX_THREAD_KEYS_MAX; i++) { if (_pthread_keys[i].created && (param = self->tsd[i])) { diff --git a/pthreads/sched.h b/pthreads/sched.h index d67a482..68cc30d 100644 --- a/pthreads/sched.h +++ b/pthreads/sched.h @@ -1,8 +1,35 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 _SCHED_H_ #define _SCHED_H_ #include +#include +__BEGIN_DECLS /* * Scheduling paramters */ @@ -13,5 +40,7 @@ struct sched_param { int sched_priority; char opaque[__SCHED_PARAM_SIZE__]; }; extern int sched_yield(void); extern int sched_get_priority_min(int); extern int sched_get_priority_max(int); +__END_DECLS + #endif /* _SCHED_H_ */ diff --git a/pthreads/stack.s b/pthreads/stack.s index 7548bbf..ee3ec0c 100644 --- a/pthreads/stack.s +++ b/pthreads/stack.s @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 diff --git a/pthreads/thread_setup.c b/pthreads/thread_setup.c index 28c08f5..5052e20 100644 --- a/pthreads/thread_setup.c +++ b/pthreads/thread_setup.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 diff --git a/regex/FreeBSD/COPYRIGHT b/regex/FreeBSD/COPYRIGHT new file mode 100644 index 0000000..574f6bc --- /dev/null +++ b/regex/FreeBSD/COPYRIGHT @@ -0,0 +1,56 @@ +Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved. +This software is not subject to any license of the American Telephone +and Telegraph Company or of the Regents of the University of California. + +Permission is granted to anyone to use this software for any purpose on +any computer system, and to alter it and redistribute it, subject +to the following restrictions: + +1. The author is not responsible for the consequences of use of this + software, no matter how awful, even if they arise from flaws in it. + +2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. Since few users ever read sources, + credits must appear in the documentation. + +3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation. + +4. This notice may not be removed or altered. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/*- + * Copyright (c) 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. + * + * @(#)COPYRIGHT 8.1 (Berkeley) 3/16/94 + */ diff --git a/regex/FreeBSD/WHATSNEW b/regex/FreeBSD/WHATSNEW new file mode 100644 index 0000000..f4301d3 --- /dev/null +++ b/regex/FreeBSD/WHATSNEW @@ -0,0 +1,94 @@ +# @(#)WHATSNEW 8.3 (Berkeley) 3/18/94 + +New in alpha3.4: The complex bug alluded to below has been fixed (in a +slightly kludgey temporary way that may hurt efficiency a bit; this is +another "get it out the door for 4.4" release). The tests at the end of +the tests file have accordingly been uncommented. The primary sign of +the bug was that something like a?b matching ab matched b rather than ab. +(The bug was essentially specific to this exact situation, else it would +have shown up earlier.) + +New in alpha3.3: The definition of word boundaries has been altered +slightly, to more closely match the usual programming notion that "_" +is an alphabetic. Stuff used for pre-ANSI systems is now in a subdir, +and the makefile no longer alludes to it in mysterious ways. The +makefile has generally been cleaned up some. Fixes have been made +(again!) so that the regression test will run without -DREDEBUG, at +the cost of weaker checking. A workaround for a bug in some folks' + has been added. And some more things have been added to +tests, including a couple right at the end which are commented out +because the code currently flunks them (complex bug; fix coming). +Plus the usual minor cleanup. + +New in alpha3.2: Assorted bits of cleanup and portability improvement +(the development base is now a BSDI system using GCC instead of an ancient +Sun system, and the newer compiler exposed some glitches). Fix for a +serious bug that affected REs using many [] (including REG_ICASE REs +because of the way they are implemented), *sometimes*, depending on +memory-allocation patterns. The header-file prototypes no longer name +the parameters, avoiding possible name conflicts. The possibility that +some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is +now handled gracefully. "uchar" is no longer used as an internal type +name (too many people have the same idea). Still the same old lousy +performance, alas. + +New in alpha3.1: Basically nothing, this release is just a bookkeeping +convenience. Stay tuned. + +New in alpha3.0: Performance is no better, alas, but some fixes have been +made and some functionality has been added. (This is basically the "get +it out the door in time for 4.4" release.) One bug fix: regfree() didn't +free the main internal structure (how embarrassing). It is now possible +to put NULs in either the RE or the target string, using (resp.) a new +REG_PEND flag and the old REG_STARTEND flag. The REG_NOSPEC flag to +regcomp() makes all characters ordinary, so you can match a literal +string easily (this will become more useful when performance improves!). +There are now primitives to match beginnings and ends of words, although +the syntax is disgusting and so is the implementation. The REG_ATOI +debugging interface has changed a bit. And there has been considerable +internal cleanup of various kinds. + +New in alpha2.3: Split change list out of README, and moved flags notes +into Makefile. Macro-ized the name of regex(7) in regex(3), since it has +to change for 4.4BSD. Cleanup work in engine.c, and some new regression +tests to catch tricky cases thereof. + +New in alpha2.2: Out-of-date manpages updated. Regerror() acquires two +small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges +in my own test program and might be useful to others for similar purposes. +The regression test will now compile (and run) without REDEBUG. The +BRE \$ bug is fixed. Most uses of "uchar" are gone; it's all chars now. +Char/uchar parameters are now written int/unsigned, to avoid possible +portability problems with unpromoted parameters. Some unsigned casts have +been introduced to minimize portability problems with shifting into sign +bits. + +New in alpha2.1: Lots of little stuff, cleanup and fixes. The one big +thing is that regex.h is now generated, using mkh, rather than being +supplied in the distribution; due to circularities in dependencies, +you have to build regex.h explicitly by "make h". The two known bugs +have been fixed (and the regression test now checks for them), as has a +problem with assertions not being suppressed in the absence of REDEBUG. +No performance work yet. + +New in alpha2: Backslash-anything is an ordinary character, not an +error (except, of course, for the handful of backslashed metacharacters +in BREs), which should reduce script breakage. The regression test +checks *where* null strings are supposed to match, and has generally +been tightened up somewhat. Small bug fixes in parameter passing (not +harmful, but technically errors) and some other areas. Debugging +invoked by defining REDEBUG rather than not defining NDEBUG. + +New in alpha+3: full prototyping for internal routines, using a little +helper program, mkh, which extracts prototypes given in stylized comments. +More minor cleanup. Buglet fix: it's CHAR_BIT, not CHAR_BITS. Simple +pre-screening of input when a literal string is known to be part of the +RE; this does wonders for performance. + +New in alpha+2: minor bits of cleanup. Notably, the number "32" for the +word width isn't hardwired into regexec.c any more, the public header +file prototypes the functions if __STDC__ is defined, and some small typos +in the manpages have been fixed. + +New in alpha+1: improvements to the manual pages, and an important +extension, the REG_STARTEND option to regexec(). diff --git a/regex/FreeBSD/cclass.h b/regex/FreeBSD/cclass.h new file mode 100644 index 0000000..956a655 --- /dev/null +++ b/regex/FreeBSD/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/FreeBSD/cname.h b/regex/FreeBSD/cname.h new file mode 100644 index 0000000..4f0d583 --- /dev/null +++ b/regex/FreeBSD/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/FreeBSD/engine.c similarity index 83% rename from regex/engine.c rename to regex/FreeBSD/engine.c index 4bcabfb..77592de 100644 --- a/regex/engine.c +++ b/regex/FreeBSD/engine.c @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,8 +33,13 @@ * LIABILITY, OR TORT (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.13 2003/02/16 17:29:10 nectar 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 @@ -111,12 +93,12 @@ extern "C" { #endif /* === engine.c === */ -static int matcher __P((struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags)); -static char *dissect __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst)); -static char *backref __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev)); -static char *fast __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst)); -static char *slow __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst)); -static states step __P((struct re_guts *g, sopno start, sopno stop, states bef, int ch, states aft)); +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, int ch, states aft); #define BOL (OUT+1) #define EOL (BOL+1) #define BOLEOL (BOL+2) @@ -127,13 +109,13 @@ static states step __P((struct re_guts *g, sopno start, sopno stop, states bef, #define NONCHAR(c) ((c) > CHAR_MAX) #define NNONCHAR (CODEMAX-CHAR_MAX) #ifdef REDEBUG -static void print __P((struct match *m, char *caption, states st, int ch, FILE *d)); +static void print(struct match *m, char *caption, states st, int ch, FILE *d); #endif #ifdef REDEBUG -static void at __P((struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst)); +static void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); #endif #ifdef REDEBUG -static char *pchar __P((int ch)); +static char *pchar(int ch); #endif #ifdef __cplusplus @@ -153,26 +135,33 @@ static char *pchar __P((int ch)); /* - matcher - the actual matching engine - == static int matcher(register struct re_guts *g, char *string, \ + == 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) -register struct re_guts *g; +struct re_guts *g; char *string; size_t nmatch; regmatch_t pmatch[]; int eflags; { - register char *endp; - register int i; + char *endp; + int i; struct match mv; - register struct match *m = &mv; - register char *dp; - const register sopno gf = g->firststate+1; /* +1 for OEND */ - const register sopno gl = g->laststate; + 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) @@ -189,12 +178,46 @@ int eflags; /* prescreening; this does wonders for this rather slow code */ if (g->must != NULL) { - 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); + 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 */ @@ -212,6 +235,10 @@ int eflags; SETUP(m->empty); CLEAR(m->empty); + /* 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); @@ -319,30 +346,30 @@ int eflags; /* - dissect - figure out what matched what, no back references - == static char *dissect(register struct match *m, char *start, \ + == 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) -register struct match *m; +struct match *m; char *start; char *stop; sopno startst; sopno stopst; { - register int i; - register sopno ss; /* start sop of current subRE */ - register sopno es; /* end sop of current subRE */ - register char *sp; /* start of string matched by it */ - register char *stp; /* string matched by it cannot pass here */ - register char *rest; /* start of rest of string */ - register char *tail; /* string unmatched by rest of RE */ - register sopno ssub; /* start sop of subsubRE */ - register sopno esub; /* end sop of subsubRE */ - register char *ssp; /* start of string matched by subsubRE */ - register char *sep; /* end of string matched by subsubRE */ - register char *oldssp; /* previous ssp */ - register char *dp; + 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; @@ -507,30 +534,30 @@ sopno stopst; /* - backref - figure out what matched what, figuring in back references - == static char *backref(register struct match *m, char *start, \ + == 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) -register struct match *m; +struct match *m; char *start; char *stop; sopno startst; sopno stopst; sopno lev; /* PLUS nesting level */ { - register int i; - register sopno ss; /* start sop of current subRE */ - register char *sp; /* start of string matched by it */ - register sopno ssub; /* start sop of subsubRE */ - register sopno esub; /* end sop of subsubRE */ - register char *ssp; /* start of string matched by subsubRE */ - register char *dp; - register size_t len; - register int hard; - register sop s; - register regoff_t offsave; - register cset *cs; + 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; AT("back", start, stop, startst, stopst); sp = start; @@ -707,30 +734,31 @@ sopno lev; /* PLUS nesting level */ /* "can't happen" */ assert(nope); /* NOTREACHED */ + return "shut up gcc"; } /* - fast - step through the string at top speed - == static char *fast(register struct match *m, char *start, \ + == 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) -register struct match *m; +struct match *m; char *start; char *stop; sopno startst; sopno stopst; { - register states st = m->st; - register states fresh = m->fresh; - register states tmp = m->tmp; - register char *p = start; - register int c = (start == m->beginp) ? OUT : *(start-1); - register int lastc; /* previous c */ - register int flagch; - register int i; - register char *coldp; /* last p after which no match was underway */ + states st = m->st; + states fresh = m->fresh; + states tmp = m->tmp; + char *p = start; + int c = (start == m->beginp) ? OUT : *(start-1); + int lastc; /* previous c */ + int flagch; + int i; + char *coldp; /* last p after which no match was underway */ CLEAR(st); SET1(st, startst); @@ -802,26 +830,26 @@ sopno stopst; /* - slow - step through the string more deliberately - == static char *slow(register struct match *m, char *start, \ + == 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) -register struct match *m; +struct match *m; char *start; char *stop; sopno startst; sopno stopst; { - register states st = m->st; - register states empty = m->empty; - register states tmp = m->tmp; - register char *p = start; - register int c = (start == m->beginp) ? OUT : *(start-1); - register int lastc; /* previous c */ - register int flagch; - register int i; - register char *matchp; /* last p at which a match ended */ + states st = m->st; + states empty = m->empty; + states tmp = m->tmp; + char *p = start; + int c = (start == m->beginp) ? OUT : *(start-1); + int lastc; /* previous c */ + int flagch; + int i; + char *matchp; /* last p at which a match ended */ AT("slow", start, stop, startst, stopst); CLEAR(st); @@ -889,8 +917,8 @@ sopno stopst; /* - step - map set of states reachable before char to set reachable after - == static states step(register struct re_guts *g, sopno start, sopno stop, \ - == register states bef, int ch, register states aft); + == 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) @@ -903,19 +931,19 @@ sopno stopst; */ static states step(g, start, stop, bef, ch, aft) -register struct re_guts *g; +struct re_guts *g; sopno start; /* start state within strip */ sopno stop; /* state after stop state within strip */ -register states bef; /* states reachable before */ +states bef; /* states reachable before */ int ch; /* character or NONCHAR code */ -register states aft; /* states already known reachable after */ +states aft; /* states already known reachable after */ { - register cset *cs; - register sop s; - register sopno pc; - register onestate here; /* note, macros know this name */ - register sopno look; - register int i; + 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]; @@ -1031,9 +1059,9 @@ states st; int ch; FILE *d; { - register struct re_guts *g = m->g; - register int i; - register int first = 1; + struct re_guts *g = m->g; + int i; + int first = 1; if (!(m->eflags®_TRACE)) return; @@ -1049,7 +1077,7 @@ FILE *d; fprintf(d, "\n"); } -/* +/* - at - print current situation == #ifdef REDEBUG == static void at(struct match *m, char *title, char *start, char *stop, \ @@ -1092,7 +1120,7 @@ int ch; { static char pbuf[10]; - if (isprint(ch) || ch == ' ') + if (isprint((uch)ch) || ch == ' ') sprintf(pbuf, "%c", ch); else sprintf(pbuf, "\\%o", ch); diff --git a/regex/re_format.7 b/regex/FreeBSD/re_format.7 similarity index 99% rename from regex/re_format.7 rename to regex/FreeBSD/re_format.7 index 32303f2..aa0fecc 100644 --- a/regex/re_format.7 +++ b/regex/FreeBSD/re_format.7 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)re_format.7 8.3 (Berkeley) 3/20/94 -.\" $FreeBSD: src/lib/libc/regex/re_format.7,v 1.9 2001/07/15 07:53:08 dd Exp $ +.\" $FreeBSD: src/lib/libc/regex/re_format.7,v 1.10 2002/01/22 12:38:43 ru Exp $ .\" .Dd March 20, 1994 .Dt RE_FORMAT 7 @@ -121,7 +121,7 @@ An atom followed by a bound containing one integer .Em i and a comma matches -a sequence o +a sequence of .Em i or more matches of the atom. An atom followed by a bound diff --git a/regex/regcomp.c b/regex/FreeBSD/regcomp.c similarity index 61% rename from regex/regcomp.c rename to regex/FreeBSD/regcomp.c index c26826d..c479a54 100644 --- a/regex/regcomp.c +++ b/regex/FreeBSD/regcomp.c @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,8 +33,16 @@ * LIABILITY, OR TORT (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.30 2003/02/16 17:29:10 nectar Exp $"); + #include #include #include @@ -66,6 +51,8 @@ #include #include +#include "collate.h" + #include "utils.h" #include "regex2.h" @@ -96,46 +83,51 @@ extern "C" { #endif /* === regcomp.c === */ -static void p_ere __P((struct parse *p, int stop)); -static void p_ere_exp __P((struct parse *p)); -static void p_str __P((struct parse *p)); -static void p_bre __P((struct parse *p, int end1, int end2)); -static int p_simp_re __P((struct parse *p, int starordinary)); -static int p_count __P((struct parse *p)); -static void p_bracket __P((struct parse *p)); -static void p_b_term __P((struct parse *p, cset *cs)); -static void p_b_cclass __P((struct parse *p, cset *cs)); -static void p_b_eclass __P((struct parse *p, cset *cs)); -static char p_b_symbol __P((struct parse *p)); -static char p_b_coll_elem __P((struct parse *p, int endc)); -static char othercase __P((int ch)); -static void bothcases __P((struct parse *p, int ch)); -static void ordinary __P((struct parse *p, int ch)); -static void nonnewline __P((struct parse *p)); -static void repeat __P((struct parse *p, sopno start, int from, int to)); -static int seterr __P((struct parse *p, int e)); -static cset *allocset __P((struct parse *p)); -static void freeset __P((struct parse *p, cset *cs)); -static int freezeset __P((struct parse *p, cset *cs)); -static int firstch __P((struct parse *p, cset *cs)); -static int nch __P((struct parse *p, cset *cs)); -static void mcadd __P((struct parse *p, cset *cs, char *cp)); -static void mcsub __P((cset *cs, char *cp)); -static int mcin __P((cset *cs, char *cp)); -static char *mcfind __P((cset *cs, char *cp)); -static void mcinvert __P((struct parse *p, cset *cs)); -static void mccase __P((struct parse *p, cset *cs)); -static int isinsets __P((struct re_guts *g, int c)); -static int samesets __P((struct re_guts *g, int c1, int c2)); -static void categorize __P((struct parse *p, struct re_guts *g)); -static sopno dupl __P((struct parse *p, sopno start, sopno finish)); -static void doemit __P((struct parse *p, sop op, size_t opnd)); -static void doinsert __P((struct parse *p, sop op, size_t opnd, sopno pos)); -static void dofwd __P((struct parse *p, sopno pos, sop value)); -static void enlarge __P((struct parse *p, sopno size)); -static void stripsnug __P((struct parse *p, struct re_guts *g)); -static void findmust __P((struct parse *p, struct re_guts *g)); -static sopno pluscount __P((struct parse *p, struct re_guts *g)); +static void p_ere(struct parse *p, int stop); +static void p_ere_exp(struct parse *p); +static void p_str(struct parse *p); +static void p_bre(struct parse *p, int end1, int 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 char p_b_symbol(struct parse *p); +static char p_b_coll_elem(struct parse *p, int endc); +static char othercase(int ch); +static void bothcases(struct parse *p, int ch); +static void ordinary(struct parse *p, int 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 int freezeset(struct parse *p, cset *cs); +static int firstch(struct parse *p, cset *cs); +static int nch(struct parse *p, cset *cs); +static void mcadd(struct parse *p, cset *cs, char *cp) __unused; +#if used +static void mcsub(cset *cs, char *cp); +static int mcin(cset *cs, char *cp); +static char *mcfind(cset *cs, char *cp); +#endif +static void mcinvert(struct parse *p, cset *cs); +static void mccase(struct parse *p, cset *cs); +static int isinsets(struct re_guts *g, int c); +static int samesets(struct re_guts *g, int c1, int c2); +static void categorize(struct parse *p, struct re_guts *g); +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, int mccs); +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); #ifdef __cplusplus } @@ -180,6 +172,9 @@ static int never = 0; /* for use in asserts; shuts lint up */ #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); @@ -194,15 +189,15 @@ static int never = 0; /* for use in asserts; shuts lint up */ */ int /* 0 success, otherwise REG_something */ regcomp(preg, pattern, cflags) -regex_t *preg; -const char *pattern; +regex_t * __restrict preg; +const char * __restrict pattern; int cflags; { struct parse pa; - register struct re_guts *g; - register struct parse *p = &pa; - register int i; - register size_t len; + struct re_guts *g; + struct parse *p = &pa; + int i; + size_t len; #ifdef REDEBUG # define GOODFLAGS(f) (f) #else @@ -252,6 +247,9 @@ int cflags; 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->ncategories = 1; /* category 0 is "everything else" */ @@ -275,6 +273,17 @@ int cflags; categorize(p, g); 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; @@ -294,25 +303,25 @@ int cflags; /* - p_ere - ERE parser top level, concatenation and alternation - == static void p_ere(register struct parse *p, int stop); + == static void p_ere(struct parse *p, int stop); */ static void p_ere(p, stop) -register struct parse *p; +struct parse *p; int stop; /* character this ERE should end at */ { - register char c; - register sopno prevback; - register sopno prevfwd; - register sopno conc; - register int first = 1; /* is this the first alternative? */ + 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); - REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ + (void)REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ if (!EAT('|')) break; /* NOTE BREAK OUT */ @@ -340,17 +349,17 @@ int stop; /* character this ERE should end at */ /* - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op - == static void p_ere_exp(register struct parse *p); + == static void p_ere_exp(struct parse *p); */ static void p_ere_exp(p) -register struct parse *p; +struct parse *p; { - register char c; - register sopno pos; - register int count; - register int count2; - register sopno subno; + char c; + sopno pos; + int count; + int count2; + sopno subno; int wascaret = 0; assert(MORE()); /* caller should have ensured this */ @@ -359,7 +368,7 @@ register struct parse *p; pos = HERE(); switch (c) { case '(': - REQUIRE(MORE(), REG_EPAREN); + (void)REQUIRE(MORE(), REG_EPAREN); p->g->nsub++; subno = p->g->nsub; if (subno < NPAREN) @@ -372,7 +381,7 @@ register struct parse *p; assert(p->pend[subno] != 0); } EMIT(ORPAREN, subno); - MUSTEAT(')', REG_EPAREN); + (void)MUSTEAT(')', REG_EPAREN); break; #ifndef POSIX_MISTAKE case ')': /* happens only if no current unmatched ( */ @@ -415,12 +424,12 @@ register struct parse *p; p_bracket(p); break; case '\\': - REQUIRE(MORE(), REG_EESCAPE); + (void)REQUIRE(MORE(), REG_EESCAPE); c = GETNEXT(); ordinary(p, c); break; case '{': /* okay as ordinary except if digit follows */ - REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT); + (void)REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT); /* FALLTHROUGH */ default: ordinary(p, c); @@ -432,11 +441,11 @@ register struct parse *p; c = PEEK(); /* we call { a repetition if followed by a digit */ if (!( c == '*' || c == '+' || c == '?' || - (c == '{' && MORE2() && isdigit(PEEK2())) )) + (c == '{' && MORE2() && isdigit((uch)PEEK2())) )) return; /* no repetition, we're done */ NEXT(); - REQUIRE(!wascaret, REG_BADRPT); + (void)REQUIRE(!wascaret, REG_BADRPT); switch (c) { case '*': /* implemented as +? */ /* this case does not require the (y|) trick, noKLUDGE */ @@ -461,9 +470,9 @@ register struct parse *p; case '{': count = p_count(p); if (EAT(',')) { - if (isdigit(PEEK())) { + if (isdigit((uch)PEEK())) { count2 = p_count(p); - REQUIRE(count <= count2, REG_BADBR); + (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ count2 = INFINITY; } else /* just a single number */ @@ -472,7 +481,7 @@ register struct parse *p; if (!EAT('}')) { /* error heuristics */ while (MORE() && PEEK() != '}') NEXT(); - REQUIRE(MORE(), REG_EBRACE); + (void)REQUIRE(MORE(), REG_EBRACE); SETERROR(REG_BADBR); } break; @@ -482,28 +491,28 @@ register struct parse *p; return; c = PEEK(); if (!( c == '*' || c == '+' || c == '?' || - (c == '{' && MORE2() && isdigit(PEEK2())) ) ) + (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) ) return; SETERROR(REG_BADRPT); } /* - p_str - string (no metacharacters) "parser" - == static void p_str(register struct parse *p); + == static void p_str(struct parse *p); */ static void p_str(p) -register struct parse *p; +struct parse *p; { - REQUIRE(MORE(), REG_EMPTY); + (void)REQUIRE(MORE(), REG_EMPTY); while (MORE()) ordinary(p, GETNEXT()); } /* - p_bre - BRE parser top level, anchoring and concatenation - == static void p_bre(register struct parse *p, register int end1, \ - == register int end2); + == 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 @@ -514,13 +523,13 @@ register struct parse *p; */ static void p_bre(p, end1, end2) -register struct parse *p; -register int end1; /* first terminating character */ -register int end2; /* second terminating character */ +struct parse *p; +int end1; /* first terminating character */ +int end2; /* second terminating character */ { - register sopno start = HERE(); - register int first = 1; /* first subexpression? */ - register int wasdollar = 0; + sopno start = HERE(); + int first = 1; /* first subexpression? */ + int wasdollar = 0; if (EAT('^')) { EMIT(OBOL, 0); @@ -538,24 +547,24 @@ register int end2; /* second terminating character */ p->g->neol++; } - REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ + (void)REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ } /* - p_simp_re - parse a simple RE, an atom possibly followed by a repetition - == static int p_simp_re(register struct parse *p, int starordinary); + == static int p_simp_re(struct parse *p, int starordinary); */ static int /* was the simple RE an unbackslashed $? */ p_simp_re(p, starordinary) -register struct parse *p; +struct parse *p; int starordinary; /* is a leading * an ordinary character? */ { - register int c; - register int count; - register int count2; - register sopno pos; - register int i; - register sopno subno; + int c; + int count; + int count2; + sopno pos; + int i; + sopno subno; # define BACKSL (1<pend[subno] != 0); } EMIT(ORPAREN, subno); - REQUIRE(EATTWO('\\', ')'), REG_EPAREN); + (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN); break; case BACKSL|')': /* should not get here -- must be user */ case BACKSL|'}': @@ -623,10 +632,10 @@ int starordinary; /* is a leading * an ordinary character? */ p->g->backrefs = 1; break; case '*': - REQUIRE(starordinary, REG_BADRPT); + (void)REQUIRE(starordinary, REG_BADRPT); /* FALLTHROUGH */ default: - ordinary(p, c &~ BACKSL); + ordinary(p, (char)c); break; } @@ -639,9 +648,9 @@ int starordinary; /* is a leading * an ordinary character? */ } else if (EATTWO('\\', '{')) { count = p_count(p); if (EAT(',')) { - if (MORE() && isdigit(PEEK())) { + if (MORE() && isdigit((uch)PEEK())) { count2 = p_count(p); - REQUIRE(count <= count2, REG_BADBR); + (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ count2 = INFINITY; } else /* just a single number */ @@ -650,10 +659,10 @@ int starordinary; /* is a leading * an ordinary character? */ if (!EATTWO('\\', '}')) { /* error heuristics */ while (MORE() && !SEETWO('\\', '}')) NEXT(); - REQUIRE(MORE(), REG_EBRACE); + (void)REQUIRE(MORE(), REG_EBRACE); SETERROR(REG_BADBR); } - } else if (c == (unsigned char)'$') /* $ (but not \$) ends it */ + } else if (c == '$') /* $ (but not \$) ends it */ return(1); return(0); @@ -661,38 +670,37 @@ int starordinary; /* is a leading * an ordinary character? */ /* - p_count - parse a repetition count - == static int p_count(register struct parse *p); + == static int p_count(struct parse *p); */ static int /* the value */ p_count(p) -register struct parse *p; +struct parse *p; { - register int count = 0; - register int ndigits = 0; + int count = 0; + int ndigits = 0; - while (MORE() && isdigit(PEEK()) && count <= DUPMAX) { + while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) { count = count*10 + (GETNEXT() - '0'); ndigits++; } - REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); + (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); return(count); } /* - p_bracket - parse a bracketed character list - == static void p_bracket(register struct parse *p); + == static void p_bracket(struct parse *p); * * Note a significant property of this code: if the allocset() did SETERROR, * no set operations are done. */ static void p_bracket(p) -register struct parse *p; +struct parse *p; { - register char c; - register cset *cs = allocset(p); - register int invert = 0; + cset *cs = allocset(p); + int invert = 0; /* Dept of Truly Sickening Special-Case Kludges */ if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { @@ -716,14 +724,14 @@ register struct parse *p; p_b_term(p, cs); if (EAT('-')) CHadd(cs, '-'); - MUSTEAT(']', REG_EBRACK); + (void)MUSTEAT(']', REG_EBRACK); if (p->error != 0) /* don't mess things up further */ return; if (p->g->cflags®_ICASE) { - register int i; - register int ci; + int i; + int ci; for (i = p->g->csetsize - 1; i >= 0; i--) if (CHIN(cs, i) && isalpha(i)) { @@ -735,7 +743,7 @@ register struct parse *p; mccase(p, cs); } if (invert) { - register int i; + int i; for (i = p->g->csetsize - 1; i >= 0; i--) if (CHIN(cs, i)) @@ -759,16 +767,16 @@ register struct parse *p; /* - p_b_term - parse one term of a bracketed character list - == static void p_b_term(register struct parse *p, register cset *cs); + == static void p_b_term(struct parse *p, cset *cs); */ static void p_b_term(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register char c; - register char start, finish; - register int i; + char c; + char start, finish; + int i; /* classify what we've got */ switch ((MORE()) ? PEEK() : '\0') { @@ -787,21 +795,21 @@ register cset *cs; switch (c) { case ':': /* character class */ NEXT2(); - REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(MORE(), REG_EBRACK); c = PEEK(); - REQUIRE(c != '-' && c != ']', REG_ECTYPE); + (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE); p_b_cclass(p, cs); - REQUIRE(MORE(), REG_EBRACK); - REQUIRE(EATTWO(':', ']'), REG_ECTYPE); + (void)REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE); break; case '=': /* equivalence class */ NEXT2(); - REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(MORE(), REG_EBRACK); c = PEEK(); - REQUIRE(c != '-' && c != ']', REG_ECOLLATE); + (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE); p_b_eclass(p, cs); - REQUIRE(MORE(), REG_EBRACK); - REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); + (void)REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); break; default: /* symbol, ordinary character, or range */ /* xxx revision needed for multichar stuff */ @@ -815,30 +823,42 @@ register cset *cs; finish = p_b_symbol(p); } else finish = start; -/* xxx what about signed chars here... */ - REQUIRE(start <= finish, REG_ERANGE); - for (i = start; i <= finish; i++) - CHadd(cs, i); + if (start == finish) + CHadd(cs, start); + else { + if (__collate_load_error) { + (void)REQUIRE((uch)start <= (uch)finish, REG_ERANGE); + for (i = (uch)start; i <= (uch)finish; i++) + CHadd(cs, i); + } else { + (void)REQUIRE(__collate_range_cmp(start, finish) <= 0, REG_ERANGE); + for (i = CHAR_MIN; i <= CHAR_MAX; i++) { + if ( __collate_range_cmp(start, i) <= 0 + && __collate_range_cmp(i, finish) <= 0 + ) + CHadd(cs, i); + } + } + } break; } } /* - p_b_cclass - parse a character-class name and deal with it - == static void p_b_cclass(register struct parse *p, register cset *cs); + == static void p_b_cclass(struct parse *p, cset *cs); */ static void p_b_cclass(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register char *sp = p->next; - register struct cclass *cp; - register size_t len; - register char *u; - register char c; + int c; + char *sp = p->next; + struct cclass *cp; + size_t len; - while (MORE() && isalpha(PEEK())) + while (MORE() && isalpha((uch)PEEK())) NEXT(); len = p->next - sp; for (cp = cclasses; cp->name != NULL; cp++) @@ -850,25 +870,86 @@ register cset *cs; return; } - u = cp->chars; - while ((c = *u++) != '\0') - CHadd(cs, c); + switch (cp->fidx) { + case CALNUM: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isalnum((uch)c)) + CHadd(cs, c); + break; + case CALPHA: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isalpha((uch)c)) + CHadd(cs, c); + break; + case CBLANK: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isblank((uch)c)) + CHadd(cs, c); + break; + case CCNTRL: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (iscntrl((uch)c)) + CHadd(cs, c); + break; + case CDIGIT: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isdigit((uch)c)) + CHadd(cs, c); + break; + case CGRAPH: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isgraph((uch)c)) + CHadd(cs, c); + break; + case CLOWER: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (islower((uch)c)) + CHadd(cs, c); + break; + case CPRINT: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isprint((uch)c)) + CHadd(cs, c); + break; + case CPUNCT: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (ispunct((uch)c)) + CHadd(cs, c); + break; + case CSPACE: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isspace((uch)c)) + CHadd(cs, c); + break; + case CUPPER: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isupper((uch)c)) + CHadd(cs, c); + break; + case CXDIGIT: + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (isxdigit((uch)c)) + CHadd(cs, c); + break; + } +#if 0 for (u = cp->multis; *u != '\0'; u += strlen(u) + 1) MCadd(p, cs, u); +#endif } /* - p_b_eclass - parse an equivalence-class name and deal with it - == static void p_b_eclass(register struct parse *p, register cset *cs); + == static void p_b_eclass(struct parse *p, cset *cs); * * This implementation is incomplete. xxx */ static void p_b_eclass(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register char c; + char c; c = p_b_coll_elem(p, '='); CHadd(cs, c); @@ -876,37 +957,36 @@ register cset *cs; /* - p_b_symbol - parse a character or [..]ed multicharacter collating symbol - == static char p_b_symbol(register struct parse *p); + == static char p_b_symbol(struct parse *p); */ static char /* value of symbol */ p_b_symbol(p) -register struct parse *p; +struct parse *p; { - register char value; + char value; - REQUIRE(MORE(), REG_EBRACK); + (void)REQUIRE(MORE(), REG_EBRACK); if (!EATTWO('[', '.')) return(GETNEXT()); /* collating symbol */ value = p_b_coll_elem(p, '.'); - REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); + (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(register struct parse *p, int endc); + == static char p_b_coll_elem(struct parse *p, int endc); */ static char /* value of collating element */ p_b_coll_elem(p, endc) -register struct parse *p; +struct parse *p; int endc; /* name ended by endc,']' */ { - register char *sp = p->next; - register struct cname *cp; - register int len; - register char c; + char *sp = p->next; + struct cname *cp; + int len; while (MORE() && !SEETWO(endc, ']')) NEXT(); @@ -932,6 +1012,7 @@ static char /* if no counterpart, return ch */ othercase(ch) int ch; { + ch = (uch)ch; assert(isalpha(ch)); if (isupper(ch)) return(tolower(ch)); @@ -943,19 +1024,20 @@ int ch; /* - bothcases - emit a dualcase version of a two-case character - == static void bothcases(register struct parse *p, int ch); + == static void bothcases(struct parse *p, int ch); * * Boy, is this implementation ever a kludge... */ static void bothcases(p, ch) -register struct parse *p; +struct parse *p; int ch; { - register char *oldnext = p->next; - register char *oldend = p->end; + char *oldnext = p->next; + char *oldend = p->end; char bracket[3]; + ch = (uch)ch; assert(othercase(ch) != ch); /* p_bracket() would recurse */ p->next = bracket; p->end = bracket+2; @@ -970,19 +1052,19 @@ int ch; /* - ordinary - emit an ordinary character - == static void ordinary(register struct parse *p, register int ch); + == static void ordinary(struct parse *p, int ch); */ static void ordinary(p, ch) -register struct parse *p; -register int ch; +struct parse *p; +int ch; { - register cat_t *cap = p->g->categories; + cat_t *cap = p->g->categories; - if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch) + if ((p->g->cflags®_ICASE) && isalpha((uch)ch) && othercase(ch) != ch) bothcases(p, ch); else { - EMIT(OCHAR, (unsigned char)ch); + EMIT(OCHAR, (uch)ch); if (cap[ch] == 0) cap[ch] = p->g->ncategories++; } @@ -990,16 +1072,16 @@ register int ch; /* - nonnewline - emit REG_NEWLINE version of OANY - == static void nonnewline(register struct parse *p); + == static void nonnewline(struct parse *p); * * Boy, is this implementation ever a kludge... */ static void nonnewline(p) -register struct parse *p; +struct parse *p; { - register char *oldnext = p->next; - register char *oldend = p->end; + char *oldnext = p->next; + char *oldend = p->end; char bracket[4]; p->next = bracket; @@ -1016,21 +1098,21 @@ register struct parse *p; /* - repeat - generate code for a bounded repetition, recursively if needed - == static void repeat(register struct parse *p, sopno start, int from, int to); + == static void repeat(struct parse *p, sopno start, int from, int to); */ static void repeat(p, start, from, to) -register struct parse *p; +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) */ { - register sopno finish = HERE(); + 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) - register sopno copy; + sopno copy; if (p->error != 0) /* head off possible runaway recursion */ return; @@ -1088,11 +1170,11 @@ int to; /* to this number of times (maybe INFINITY) */ /* - seterr - set an error condition - == static int seterr(register struct parse *p, int e); + == static int seterr(struct parse *p, int e); */ static int /* useless but makes type checking happy */ seterr(p, e) -register struct parse *p; +struct parse *p; int e; { if (p->error == 0) /* keep earliest error condition */ @@ -1104,18 +1186,18 @@ int e; /* - allocset - allocate a set of characters for [] - == static cset *allocset(register struct parse *p); + == static cset *allocset(struct parse *p); */ static cset * allocset(p) -register struct parse *p; +struct parse *p; { - register int no = p->g->ncsets++; - register size_t nc; - register size_t nbytes; - register cset *cs; - register size_t css = (size_t)p->g->csetsize; - register int i; + int no = p->g->ncsets++; + size_t nc; + size_t nbytes; + cset *cs; + size_t css = (size_t)p->g->csetsize; + int i; if (no >= p->ncsalloc) { /* need another column of space */ p->ncsalloc += CHAR_BIT; @@ -1125,12 +1207,12 @@ register struct parse *p; if (p->g->sets == NULL) p->g->sets = (cset *)malloc(nc * sizeof(cset)); else - p->g->sets = (cset *)realloc((char *)p->g->sets, + p->g->sets = (cset *)reallocf((char *)p->g->sets, nc * sizeof(cset)); if (p->g->setbits == NULL) p->g->setbits = (uch *)malloc(nbytes); else { - p->g->setbits = (uch *)realloc((char *)p->g->setbits, + p->g->setbits = (uch *)reallocf((char *)p->g->setbits, nbytes); /* xxx this isn't right if setbits is now NULL */ for (i = 0; i < no; i++) @@ -1159,16 +1241,16 @@ register struct parse *p; /* - freeset - free a now-unused set - == static void freeset(register struct parse *p, register cset *cs); + == static void freeset(struct parse *p, cset *cs); */ static void freeset(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register int i; - register cset *top = &p->g->sets[p->g->ncsets]; - register size_t css = (size_t)p->g->csetsize; + int i; + cset *top = &p->g->sets[p->g->ncsets]; + size_t css = (size_t)p->g->csetsize; for (i = 0; i < css; i++) CHsub(cs, i); @@ -1178,7 +1260,7 @@ register cset *cs; /* - freezeset - final processing on a set of characters - == static int freezeset(register struct parse *p, register cset *cs); + == static int freezeset(struct parse *p, cset *cs); * * The main task here is merging identical sets. This is usually a waste * of time (although the hash code minimizes the overhead), but can win @@ -1188,14 +1270,14 @@ register cset *cs; */ static int /* set number */ freezeset(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register uch h = cs->hash; - register int i; - register cset *top = &p->g->sets[p->g->ncsets]; - register cset *cs2; - register size_t css = (size_t)p->g->csetsize; + short h = cs->hash; + int i; + cset *top = &p->g->sets[p->g->ncsets]; + cset *cs2; + size_t css = (size_t)p->g->csetsize; /* look for an earlier one which is the same */ for (cs2 = &p->g->sets[0]; cs2 < top; cs2++) @@ -1218,15 +1300,15 @@ register cset *cs; /* - firstch - return first character in a set (which must have at least one) - == static int firstch(register struct parse *p, register cset *cs); + == static int firstch(struct parse *p, cset *cs); */ static int /* character; there is no "none" value */ firstch(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register int i; - register size_t css = (size_t)p->g->csetsize; + int i; + size_t css = (size_t)p->g->csetsize; for (i = 0; i < css; i++) if (CHIN(cs, i)) @@ -1237,16 +1319,16 @@ register cset *cs; /* - nch - number of characters in a set - == static int nch(register struct parse *p, register cset *cs); + == static int nch(struct parse *p, cset *cs); */ static int nch(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { - register int i; - register size_t css = (size_t)p->g->csetsize; - register int n = 0; + int i; + size_t css = (size_t)p->g->csetsize; + int n = 0; for (i = 0; i < css; i++) if (CHIN(cs, i)) @@ -1256,22 +1338,22 @@ register cset *cs; /* - mcadd - add a collating element to a cset - == static void mcadd(register struct parse *p, register cset *cs, \ - == register char *cp); + == static void mcadd(struct parse *p, cset *cs, \ + == char *cp); */ static void mcadd(p, cs, cp) -register struct parse *p; -register cset *cs; -register char *cp; +struct parse *p; +cset *cs; +char *cp; { - register size_t oldend = cs->smultis; + size_t oldend = cs->smultis; cs->smultis += strlen(cp) + 1; if (cs->multis == NULL) cs->multis = malloc(cs->smultis); else - cs->multis = realloc(cs->multis, cs->smultis); + cs->multis = reallocf(cs->multis, cs->smultis); if (cs->multis == NULL) { SETERROR(REG_ESPACE); return; @@ -1281,17 +1363,18 @@ register char *cp; cs->multis[cs->smultis - 1] = '\0'; } +#if used /* - mcsub - subtract a collating element from a cset - == static void mcsub(register cset *cs, register char *cp); + == static void mcsub(cset *cs, char *cp); */ static void mcsub(cs, cp) -register cset *cs; -register char *cp; +cset *cs; +char *cp; { - register char *fp = mcfind(cs, cp); - register size_t len = strlen(fp); + char *fp = mcfind(cs, cp); + size_t len = strlen(fp); assert(fp != NULL); (void) memmove(fp, fp + len + 1, @@ -1304,32 +1387,32 @@ register char *cp; return; } - cs->multis = realloc(cs->multis, cs->smultis); + cs->multis = reallocf(cs->multis, cs->smultis); assert(cs->multis != NULL); } /* - mcin - is a collating element in a cset? - == static int mcin(register cset *cs, register char *cp); + == static int mcin(cset *cs, char *cp); */ static int mcin(cs, cp) -register cset *cs; -register char *cp; +cset *cs; +char *cp; { return(mcfind(cs, cp) != NULL); } /* - mcfind - find a collating element in a cset - == static char *mcfind(register cset *cs, register char *cp); + == static char *mcfind(cset *cs, char *cp); */ static char * mcfind(cs, cp) -register cset *cs; -register char *cp; +cset *cs; +char *cp; { - register char *p; + char *p; if (cs->multis == NULL) return(NULL); @@ -1338,50 +1421,51 @@ register char *cp; return(p); return(NULL); } +#endif /* - mcinvert - invert the list of collating elements in a cset - == static void mcinvert(register struct parse *p, register cset *cs); + == static void mcinvert(struct parse *p, cset *cs); * * This would have to know the set of possibilities. Implementation * is deferred. */ static void mcinvert(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { assert(cs->multis == NULL); /* xxx */ } /* - mccase - add case counterparts of the list of collating elements in a cset - == static void mccase(register struct parse *p, register cset *cs); + == static void mccase(struct parse *p, cset *cs); * * This would have to know the set of possibilities. Implementation * is deferred. */ static void mccase(p, cs) -register struct parse *p; -register cset *cs; +struct parse *p; +cset *cs; { assert(cs->multis == NULL); /* xxx */ } /* - isinsets - is this character in any sets? - == static int isinsets(register struct re_guts *g, int c); + == static int isinsets(struct re_guts *g, int c); */ static int /* predicate */ isinsets(g, c) -register struct re_guts *g; +struct re_guts *g; int c; { - register uch *col; - register int i; - register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; - register unsigned uc = (unsigned char)c; + uch *col; + int i; + int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; + unsigned uc = (uch)c; for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) if (col[uc] != 0) @@ -1391,19 +1475,19 @@ int c; /* - samesets - are these two characters in exactly the same sets? - == static int samesets(register struct re_guts *g, int c1, int c2); + == static int samesets(struct re_guts *g, int c1, int c2); */ static int /* predicate */ samesets(g, c1, c2) -register struct re_guts *g; +struct re_guts *g; int c1; int c2; { - register uch *col; - register int i; - register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; - register unsigned uc1 = (unsigned char)c1; - register unsigned uc2 = (unsigned char)c2; + uch *col; + int i; + int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; + unsigned uc1 = (uch)c1; + unsigned uc2 = (uch)c2; for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) if (col[uc1] != col[uc2]) @@ -1413,17 +1497,17 @@ int c2; /* - categorize - sort out character categories - == static void categorize(struct parse *p, register struct re_guts *g); + == static void categorize(struct parse *p, struct re_guts *g); */ static void categorize(p, g) struct parse *p; -register struct re_guts *g; +struct re_guts *g; { - register cat_t *cats = g->categories; - register int c; - register int c2; - register cat_t cat; + cat_t *cats = g->categories; + int c; + int c2; + cat_t cat; /* avoid making error situations worse */ if (p->error != 0) @@ -1441,16 +1525,16 @@ register struct re_guts *g; /* - dupl - emit a duplicate of a bunch of sops - == static sopno dupl(register struct parse *p, sopno start, sopno finish); + == static sopno dupl(struct parse *p, sopno start, sopno finish); */ static sopno /* start of duplicate */ dupl(p, start, finish) -register struct parse *p; +struct parse *p; sopno start; /* from here */ sopno finish; /* to this less one */ { - register sopno ret = HERE(); - register sopno len = finish - start; + sopno ret = HERE(); + sopno len = finish - start; assert(finish >= start); if (len == 0) @@ -1465,7 +1549,7 @@ sopno finish; /* to this less one */ /* - doemit - emit a strip operator - == static void doemit(register struct parse *p, sop op, size_t opnd); + == 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 @@ -1473,7 +1557,7 @@ sopno finish; /* to this less one */ */ static void doemit(p, op, opnd) -register struct parse *p; +struct parse *p; sop op; size_t opnd; { @@ -1495,18 +1579,18 @@ size_t opnd; /* - doinsert - insert a sop into the strip - == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos); + == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); */ static void doinsert(p, op, opnd, pos) -register struct parse *p; +struct parse *p; sop op; size_t opnd; sopno pos; { - register sopno sn; - register sop s; - register int i; + sopno sn; + sop s; + int i; /* avoid making error situations worse */ if (p->error != 0) @@ -1535,12 +1619,12 @@ sopno pos; /* - dofwd - complete a forward reference - == static void dofwd(register struct parse *p, sopno pos, sop value); + == static void dofwd(struct parse *p, sopno pos, sop value); */ static void dofwd(p, pos, value) -register struct parse *p; -register sopno pos; +struct parse *p; +sopno pos; sop value; { /* avoid making error situations worse */ @@ -1553,14 +1637,14 @@ sop value; /* - enlarge - enlarge the strip - == static void enlarge(register struct parse *p, sopno size); + == static void enlarge(struct parse *p, sopno size); */ static void enlarge(p, size) -register struct parse *p; -register sopno size; +struct parse *p; +sopno size; { - register sop *sp; + sop *sp; if (p->ssize >= size) return; @@ -1576,12 +1660,12 @@ register sopno size; /* - stripsnug - compact the strip - == static void stripsnug(register struct parse *p, register struct re_guts *g); + == static void stripsnug(struct parse *p, struct re_guts *g); */ static void stripsnug(p, g) -register struct parse *p; -register struct re_guts *g; +struct parse *p; +struct re_guts *g; { g->nstates = p->slen; g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); @@ -1593,7 +1677,7 @@ register struct re_guts *g; /* - findmust - fill in must and mlen with longest mandatory literal string - == static void findmust(register struct parse *p, register struct re_guts *g); + == 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 @@ -1604,22 +1688,32 @@ register struct re_guts *g; static void findmust(p, g) struct parse *p; -register struct re_guts *g; +struct re_guts *g; { - register sop *scan; + sop *scan; sop *start; - register sop *newstart; - register sopno newlen; - register sop s; - register char *cp; - register sopno i; + sop *newstart; + sopno newlen; + sop s; + char *cp; + sopno i; + int offset; + int cs, mccs; /* avoid making error situations worse */ if (p->error != 0) return; + /* Find out if we can handle OANYOF or not */ + mccs = 0; + for (cs = 0; cs < g->ncsets; cs++) + if (g->sets[cs].multis != NULL) + mccs = 1; + /* find the longest OCHAR sequence in strip */ newlen = 0; + offset = 0; + g->moffset = 0; scan = g->strip + 1; do { s = *scan++; @@ -1635,6 +1729,7 @@ register struct re_guts *g; break; case OQUEST_: /* things that must be skipped */ case OCH_: + offset = altoffset(scan, offset, mccs); scan--; do { scan += OPND(s); @@ -1646,24 +1741,98 @@ register struct re_guts *g; return; } } while (OP(s) != O_QUEST && OP(s) != O_CH); - /* fallthrough */ - default: /* things that break a sequence */ + /* 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; + /* And, now, if we found out we can't deal with + * it, make offset = -1. + */ + if (mccs) + offset = -1; + break; + 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 */ + 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; @@ -1678,19 +1847,224 @@ register struct re_guts *g; *cp++ = '\0'; /* just on general principles */ } +/* + - altoffset - choose biggest offset among multiple choices + == static int altoffset(sop *scan, int offset, int mccs); + * + * Compute, recursively if necessary, the largest offset among multiple + * re paths. + */ +static int +altoffset(scan, offset, mccs) +sop *scan; +int offset; +int mccs; +{ + 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, mccs); + 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: + if (mccs) + return -1; + 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(register struct parse *p, register struct re_guts *g); + == static sopno pluscount(struct parse *p, struct re_guts *g); */ static sopno /* nesting depth */ pluscount(p, g) struct parse *p; -register struct re_guts *g; +struct re_guts *g; { - register sop *scan; - register sop s; - register sopno plusnest = 0; - register sopno maxnest = 0; + sop *scan; + sop s; + sopno plusnest = 0; + sopno maxnest = 0; if (p->error != 0) return(0); /* there may not be an OEND */ diff --git a/regex/regerror.c b/regex/FreeBSD/regerror.c similarity index 64% rename from regex/regerror.c rename to regex/FreeBSD/regerror.c index e922ac9..f2a2116 100644 --- a/regex/regerror.c +++ b/regex/FreeBSD/regerror.c @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,16 +33,19 @@ * LIABILITY, OR TORT (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.8 2002/10/02 07:49:35 mike Exp $"); #include #include #include -#include #include #include #include @@ -78,7 +58,7 @@ extern "C" { #endif /* === regerror.c === */ -static char *regatoi __P((const regex_t *preg, char *localbuf)); +static char *regatoi(const regex_t *preg, char *localbuf); #ifdef __cplusplus } @@ -109,23 +89,23 @@ static struct rerr { 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", - 0, "", "*** unknown regexp error code ***", + {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"}, + {0, "", "*** unknown regexp error code ***"} }; /* @@ -136,14 +116,14 @@ static struct rerr { size_t regerror(errcode, preg, errbuf, errbuf_size) int errcode; -const regex_t *preg; -char *errbuf; +const regex_t * __restrict preg; +char * __restrict errbuf; size_t errbuf_size; { - register struct rerr *r; - register size_t len; - register int target = errcode &~ REG_ITOA; - register char *s; + struct rerr *r; + size_t len; + int target = errcode &~ REG_ITOA; + char *s; char convbuf[50]; if (errcode == REG_ATOI) @@ -152,7 +132,7 @@ size_t errbuf_size; for (r = rerrs; r->code != 0; r++) if (r->code == target) break; - + if (errcode®_ITOA) { if (r->code != 0) (void) strcpy(convbuf, r->name); @@ -186,9 +166,7 @@ regatoi(preg, localbuf) const regex_t *preg; char *localbuf; { - register struct rerr *r; - register size_t siz; - register char *p; + struct rerr *r; for (r = rerrs; r->code != 0; r++) if (strcmp(r->name, preg->re_endp) == 0) diff --git a/regex/regex.3 b/regex/FreeBSD/regex.3 similarity index 95% rename from regex/regex.3 rename to regex/FreeBSD/regex.3 index d871641..cf46cd4 100644 --- a/regex/regex.3 +++ b/regex/FreeBSD/regex.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)regex.3 8.4 (Berkeley) 3/20/94 -.\" $FreeBSD: src/lib/libc/regex/regex.3,v 1.9 2001/10/01 16:08:58 ru Exp $ +.\" $FreeBSD: src/lib/libc/regex/regex.3,v 1.12 2002/12/19 09:40:23 ru Exp $ .\" -.Dd March 20, 1994 +.Dd October 2, 2002 .Dt REGEX 3 .Os .Sh NAME @@ -48,19 +48,20 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In sys/types.h .In regex.h .Ft int -.Fn regcomp "regex_t *preg" "const char *pattern" "int cflags" +.Fo regcomp +.Fa "regex_t * restrict preg" "const char * restrict pattern" "int cflags" +.Fc .Ft int .Fo regexec -.Fa "const regex_t *preg" "const char *string" -.Fa "size_t nmatch" "regmatch_t pmatch[]" "int eflags" +.Fa "const regex_t * restrict preg" "const char * restrict string" +.Fa "size_t nmatch" "regmatch_t pmatch[restrict]" "int eflags" .Fc .Ft size_t .Fo regerror -.Fa "int errcode" "const regex_t *preg" -.Fa "char *errbuf" "size_t errbuf_size" +.Fa "int errcode" "const regex_t * restrict preg" +.Fa "char * restrict errbuf" "size_t errbuf_size" .Fc .Ft void .Fn regfree "regex_t *preg" @@ -71,7 +72,9 @@ regular expressions .Pq Do RE Dc Ns s ; see .Xr re_format 7 . -.Fn Regcomp +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, @@ -95,7 +98,9 @@ a type and a number of constants with names starting with .Dq Dv REG_ . .Pp -.Fn Regcomp +The +.Fn regcomp +function compiles the regular expression contained in the .Fa pattern string, @@ -105,7 +110,9 @@ and places the results in the .Ft regex_t structure pointed to by .Fa preg . -.Fa Cflags +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 @@ -203,7 +210,9 @@ fails, it returns a non-zero error code; see .Sx DIAGNOSTICS . .Pp -.Fn Regexec +The +.Fn regexec +function matches the compiled RE pointed to by .Fa preg against the @@ -389,7 +398,9 @@ the value of will not be changed by a successful .Fn regexec . .Pp -.Fn Regerror +The +.Fn regerror +function maps a non-zero .Fa errcode from either @@ -412,11 +423,14 @@ it should have been the result from the most recent .Fn regcomp using that .Ft regex_t . -.No ( Fn Regerror +The +.Fn ( regerror may be able to supply a more detailed message using information from the .Ft regex_t . ) -.Fn Regerror +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 @@ -473,7 +487,9 @@ 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 -.Fn Regfree +The +.Fn regfree +function frees any dynamically-allocated storage associated with the compiled RE pointed to by .Fa preg . @@ -589,7 +605,9 @@ 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 @@ -648,14 +666,20 @@ Please report problems. The back-reference code is subtle and doubts linger about its correctness in complex cases. .Pp -.Fn Regexec +The +.Fn regexec +function performance is poor. This will improve with later releases. -.Fa Nmatch +The +.Fa nmatch +argument exceeding 0 is expensive; .Fa nmatch exceeding 1 is worse. -.Fn Regexec +The +.Fn regexec +function is largely insensitive to RE complexity .Em except that back @@ -664,7 +688,9 @@ 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 -.Fn Regcomp +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. diff --git a/regex/regex2.h b/regex/FreeBSD/regex2.h similarity index 71% rename from regex/regex2.h rename to regex/FreeBSD/regex2.h index 71698f1..303b7f7 100644 --- a/regex/regex2.h +++ b/regex/FreeBSD/regex2.h @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,6 +33,9 @@ * LIABILITY, OR TORT (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.6 2002/03/22 23:41:56 obrien Exp $ */ /* @@ -98,34 +78,34 @@ */ typedef unsigned long sop; /* strip operator */ typedef long sopno; -#define OPRMASK 0xf8000000 -#define OPDMASK 0x07ffffff +#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 (1< uch [csetsize] */ uch mask; /* bit within array */ - uch hash; /* hash code */ + short hash; /* hash code */ size_t smultis; char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */ } cset; /* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */ -#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c)) -#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c)) +#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (uch)(c)) +#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (uch)(c)) #define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask) #define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */ #define MCsub(p, cs, cp) mcsub(p, cs, cp) @@ -181,6 +161,9 @@ struct re_guts { int ncategories; /* how many character categories */ cat_t *categories; /* ->catspace[-CHAR_MIN] */ 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? */ @@ -191,4 +174,4 @@ struct re_guts { /* misc utilities */ #define OUT (CHAR_MAX+1) /* a non-character value */ -#define ISWORD(c) (isalnum(c) || (c) == '_') +#define ISWORD(c) (isalnum((uch)(c)) || (c) == '_') diff --git a/regex/regexec.c b/regex/FreeBSD/regexec.c similarity index 75% rename from regex/regexec.c rename to regex/FreeBSD/regexec.c index 682550e..e91938e 100644 --- a/regex/regexec.c +++ b/regex/FreeBSD/regexec.c @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,8 +33,16 @@ * LIABILITY, OR TORT (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.5 2003/02/16 17:29:10 nectar Exp $"); + /* * the outer shell of regexec() * @@ -76,30 +61,30 @@ #include "utils.h" #include "regex2.h" -static int nope = 0; /* for use in asserts; shuts lint up */ +static int nope __unused = 0; /* for use in asserts; shuts lint up */ /* 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) &= ~(1 << (n))) -#define SET1(v, n) ((v) |= 1 << (n)) -#define ISSET(v, n) ((v) & (1 << (n))) +#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 int dummy /* dummy version */ +#define STATEVARS long dummy /* dummy version */ #define STATESETUP(m, n) /* nothing */ #define STATETEARDOWN(m) /* nothing */ #define SETUP(v) ((v) = 0) -#define onestate int -#define INIT(o, n) ((o) = (unsigned)1 << (n)) +#define onestate long +#define INIT(o, n) ((o) = (unsigned long)1 << (n)) #define INC(o) ((o) <<= 1) -#define ISSTATEIN(v, o) ((v) & (o)) +#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)(src)&(here)) << (n)) -#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n)) -#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n))) +#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) /* function names */ #define SNAMES /* engine.c looks after details */ @@ -134,13 +119,13 @@ static int nope = 0; /* for use in asserts; shuts lint up */ #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 int vn; char *space +#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 int +#define onestate long #define INIT(o, n) ((o) = (n)) #define INC(o) ((o)++) #define ISSTATEIN(v, o) ((v)[o]) @@ -171,13 +156,13 @@ static int nope = 0; /* for use in asserts; shuts lint up */ */ int /* 0 success, REG_NOMATCH failure */ regexec(preg, string, nmatch, pmatch, eflags) -const regex_t *preg; -const char *string; +const regex_t * __restrict preg; +const char * __restrict string; size_t nmatch; -regmatch_t pmatch[]; +regmatch_t pmatch[__restrict]; int eflags; { - register struct re_guts *g = preg->re_g; + struct re_guts *g = preg->re_g; #ifdef REDEBUG # define GOODFLAGS(f) (f) #else diff --git a/regex/FreeBSD/regexec.c.patch b/regex/FreeBSD/regexec.c.patch new file mode 100644 index 0000000..986eda9 --- /dev/null +++ b/regex/FreeBSD/regexec.c.patch @@ -0,0 +1,11 @@ +--- regexec.c.orig Sun Feb 16 09:29:10 2003 ++++ regexec.c Sat May 3 14:21:16 2003 +@@ -137,6 +137,8 @@ + /* function names */ + #define LNAMES /* flag */ + ++#undef __FBSDID ++#define __FBSDID(x) + #include "engine.c" + + /* diff --git a/regex/regfree.c b/regex/FreeBSD/regfree.c similarity index 71% rename from regex/regfree.c rename to regex/FreeBSD/regfree.c index cc979c5..82119d3 100644 --- a/regex/regfree.c +++ b/regex/FreeBSD/regfree.c @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,15 +33,20 @@ * LIABILITY, OR TORT (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.5 2002/03/22 21:52:47 obrien Exp $"); #include #include #include +#include #include #include "utils.h" @@ -78,7 +60,7 @@ void regfree(preg) regex_t *preg; { - register struct re_guts *g; + struct re_guts *g; if (preg->re_magic != MAGIC1) /* oops */ return; /* nice to complain, but hard */ @@ -97,5 +79,9 @@ regex_t *preg; free((char *)g->setbits); 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/FreeBSD/utils.h similarity index 69% rename from regex/utils.h rename to regex/FreeBSD/utils.h index 197b068..5439b6c 100644 --- a/regex/utils.h +++ b/regex/FreeBSD/utils.h @@ -1,28 +1,5 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -56,6 +33,9 @@ * LIABILITY, OR TORT (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 */ diff --git a/regex/Makefile.inc b/regex/Makefile.inc index a71b092..8eb7f04 100644 --- a/regex/Makefile.inc +++ b/regex/Makefile.inc @@ -6,11 +6,16 @@ CFLAGS+=-DPOSIX_MISTAKE -SRCS+= regcomp.c regerror.c regexec.c regfree.c +.include "Makefile.fbsd_begin" +FBSDSRCS= regcomp.c regerror.c regexec.c regfree.c +FBSDORIGHDRS= cclass.h cname.h engine.c regex2.h utils.h +.include "Makefile.fbsd_end" .if ${LIB} == "c" -MAN3+= regex.3 -MAN7+= re_format.7 +.include "Makefile.fbsd_begin" +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 diff --git a/regex/cclass.h b/regex/cclass.h deleted file mode 100644 index 14f083a..0000000 --- a/regex/cclass.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 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. - */ - -/* character-class table */ -static struct cclass { - char *name; - char *chars; - char *multis; -} cclasses[] = { - "alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ -0123456789", "", - "alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - "", - "blank", " \t", "", - "cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\ -\25\26\27\30\31\32\33\34\35\36\37\177", "", - "digit", "0123456789", "", - "graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ -0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - "", - "lower", "abcdefghijklmnopqrstuvwxyz", - "", - "print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ -0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ", - "", - "punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - "", - "space", "\t\n\v\f\r ", "", - "upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", - "", - "xdigit", "0123456789ABCDEFabcdef", - "", - NULL, 0, "" -}; diff --git a/regex/cname.h b/regex/cname.h deleted file mode 100644 index 275986d..0000000 --- a/regex/cname.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 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. - */ - -/* character-name table */ -static const 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/stdio/FreeBSD/_flock_stub.c b/stdio/FreeBSD/_flock_stub.c new file mode 100644 index 0000000..2322a7f --- /dev/null +++ b/stdio/FreeBSD/_flock_stub.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.12 2002/03/22 21:53:04 obrien 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.c b/stdio/FreeBSD/asprintf.c similarity index 76% rename from stdio/asprintf.c rename to stdio/FreeBSD/asprintf.c index e0da796..02362b0 100644 --- a/stdio/asprintf.c +++ b/stdio/FreeBSD/asprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asprintf.c,v 1.4 1998/06/21 22:13:46 millert Exp $ */ +/* $OpenBSD: asprintf.c,v 1.8 2002/02/19 19:39:36 millert Exp $ */ /* * Copyright (c) 1997 Todd C. Miller @@ -27,38 +27,24 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(LIBC_RCS) && !defined(lint) -static char rcsid[] = "$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.6 1999/08/28 00:00:55 peter Exp $"; -#endif /* LIBC_RCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.13 2002/09/26 13:09:48 tjr Exp $"); #include #include #include -#if __STDC__ #include -#else -#include -#endif + +#include "local.h" int -#if __STDC__ asprintf(char **str, char const *fmt, ...) -#else -asprintf(str, fmt, va_alist) - char **str; - const char *fmt; - va_dcl -#endif { int ret; va_list ap; FILE f; + struct __sFILEX ext; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); @@ -67,15 +53,19 @@ asprintf(str, fmt, va_alist) errno = ENOMEM; return (-1); } - f._bf._size = f._w = 127; /* Leave room for the NULL */ - ret = vfprintf(&f, fmt, ap); - *f._p = '\0'; + f._bf._size = f._w = 127; /* Leave room for the NUL */ + f._extra = &ext; + INITEXTRA(&f); + va_start(ap, fmt); + ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ va_end(ap); - f._bf._base = reallocf(f._bf._base, f._bf._size + 1); - if (f._bf._base == NULL) { + if (ret < 0) { + free(f._bf._base); + *str = NULL; errno = ENOMEM; - ret = -1; + return (-1); } + *f._p = '\0'; *str = (char *)f._bf._base; return (ret); } diff --git a/stdio/clrerr.c b/stdio/FreeBSD/clrerr.c similarity index 65% rename from stdio/clrerr.c rename to stdio/FreeBSD/clrerr.c index db72232..bfac2c1 100644 --- a/stdio/clrerr.c +++ b/stdio/FreeBSD/clrerr.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,23 @@ * 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.3 b/stdio/FreeBSD/fclose.3 similarity index 97% rename from stdio/fclose.3 rename to stdio/FreeBSD/fclose.3 index 5dded81..8adc65a 100644 --- a/stdio/fclose.3 +++ b/stdio/FreeBSD/fclose.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fclose.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fclose.3,v 1.11 2001/10/01 16:08:58 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fclose.3,v 1.12 2002/12/18 12:45:10 ru Exp $ .\" .Dd June 4, 1993 .Dt FCLOSE 3 @@ -77,7 +77,9 @@ for any of the errors specified for the routines or .Xr fflush 3 . .Sh NOTES +The .Fn fclose +function does not handle NULL arguments; they will result in a segmentation violation. This is intentional - it makes it easier to make sure programs written diff --git a/stdio/fclose.c b/stdio/FreeBSD/fclose.c similarity index 68% rename from stdio/fclose.c rename to stdio/FreeBSD/fclose.c index bd4f1a4..ad4dae7 100644 --- a/stdio/fclose.c +++ b/stdio/FreeBSD/fclose.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,22 +34,30 @@ * 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(fp) - register FILE *fp; +fclose(FILE *fp) { - register int r; + int r; 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; @@ -83,7 +67,9 @@ fclose(fp) FREEUB(fp); if (HASLB(fp)) FREELB(fp); - fp->_flags = 0; /* Release this FILE for reuse. */ + 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/fdopen.c b/stdio/FreeBSD/fdopen.c similarity index 69% rename from stdio/fdopen.c rename to stdio/FreeBSD/fdopen.c index f36f9bd..15e7e8f 100644 --- a/stdio/fdopen.c +++ b/stdio/FreeBSD/fdopen.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,12 +34,19 @@ * 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 * @@ -71,7 +54,7 @@ fdopen(fd, mode) int fd; const char *mode; { - register FILE *fp; + FILE *fp; static int nofile; int flags, oflags, fdflags, tmp; @@ -82,7 +65,7 @@ fdopen(fd, mode) return (NULL); /* Make sure the mode the user wants is a subset of the actual mode. */ - if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) + if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) return (NULL); tmp = fdflags & O_ACCMODE; if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { @@ -95,8 +78,8 @@ fdopen(fd, mode) fp->_flags = flags; /* * If opened for appending, but underlying descriptor does not have - * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to - * end before each write. + * 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; diff --git a/stdio/FreeBSD/feof.c b/stdio/FreeBSD/feof.c new file mode 100644 index 0000000..8b1cf41 --- /dev/null +++ b/stdio/FreeBSD/feof.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[] = "@(#)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.8 2002/03/22 21:53:04 obrien Exp $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* + * feof has traditionally been a macro in . That is no + * longer true because it needs to be thread-safe. + * + * #undef feof + */ +int +feof(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret= __sfeof(fp); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/ferror.3 b/stdio/FreeBSD/ferror.3 similarity index 79% rename from stdio/ferror.3 rename to stdio/FreeBSD/ferror.3 index ff8b1f6..6e7d1ba 100644 --- a/stdio/ferror.3 +++ b/stdio/FreeBSD/ferror.3 @@ -34,16 +34,20 @@ .\" SUCH DAMAGE. .\" .\" @(#)ferror.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdio/ferror.3,v 1.6 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/ferror.3,v 1.9 2003/02/23 01:47:47 ru Exp $ .\" -.Dd April 19, 1994 +.Dd January 10, 2003 .Dt FERROR 3 .Os .Sh NAME .Nm clearerr , +.Nm clearerr_unlocked , .Nm feof , +.Nm feof_unlocked , .Nm ferror , -.Nm fileno +.Nm ferror_unlocked , +.Nm fileno , +.Nm fileno_unlocked .Nd check and reset stream status .Sh LIBRARY .Lb libc @@ -51,12 +55,20 @@ .In stdio.h .Ft void .Fn clearerr "FILE *stream" +.Ft void +.Fn clearerr_unlocked "FILE *stream" .Ft int .Fn feof "FILE *stream" .Ft int +.Fn feof_unlocked "FILE *stream" +.Ft int .Fn ferror "FILE *stream" .Ft int +.Fn ferror_unlocked "FILE *stream" +.Ft int .Fn fileno "FILE *stream" +.Ft int +.Fn fileno_unlocked "FILE *stream" .Sh DESCRIPTION The function .Fn clearerr @@ -86,12 +98,33 @@ The function examines the argument .Fa stream and returns its integer descriptor. +.Pp +The +.Fn clearerr_unlocked , +.Fn feof_unlocked , +.Fn ferror_unlocked , +and +.Fn fileno_unlocked +functions are equivalent to +.Fn clearerr , +.Fn feof , +.Fn ferror , +and +.Fn fileno +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 +and to prevent races when multiple threads are operating on the same stream. .Sh ERRORS These functions should not fail and do not set the external variable .Va errno . .Sh SEE ALSO .Xr open 2 , +.Xr fdopen 3 , +.Xr flockfile 3 , .Xr stdio 3 .Sh STANDARDS The functions diff --git a/stdio/FreeBSD/ferror.c b/stdio/FreeBSD/ferror.c new file mode 100644 index 0000000..11e5f7d --- /dev/null +++ b/stdio/FreeBSD/ferror.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[] = "@(#)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.8 2002/03/22 21:53:04 obrien Exp $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* + * ferror has traditionally been a macro in . That is no + * longer true because it needs to be thread-safe. + * + * #undef ferror + */ +int +ferror(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret = __sferror(fp); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/fflush.3 b/stdio/FreeBSD/fflush.3 similarity index 96% rename from stdio/fflush.3 rename to stdio/FreeBSD/fflush.3 index 37c7dcd..cc3e7e8 100644 --- a/stdio/fflush.3 +++ b/stdio/FreeBSD/fflush.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fflush.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.8 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.10 2003/06/08 10:01:52 charnier Exp $ .\" .Dd June 4, 1993 .Dt FFLUSH 3 @@ -77,7 +77,7 @@ For input streams this discards any input read from the underlying object but not yet obtained via .Xr getc 3 ; this includes any text pushed back via -.Xr ungetc . +.Xr ungetc 3 . .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, @@ -88,7 +88,9 @@ is set to indicate the error. .Sh ERRORS .Bl -tag -width Er .It Bq Er EBADF -.Fa Stream +The +.Fa stream +argument is not an open stream, or, in the case of .Fn fflush , not a stream open for writing. diff --git a/stdio/fflush.c b/stdio/FreeBSD/fflush.c similarity index 65% rename from stdio/fflush.c rename to stdio/FreeBSD/fflush.c index d938c25..5732410 100644 --- a/stdio/fflush.c +++ b/stdio/FreeBSD/fflush.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,32 +34,66 @@ * 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.12 2002/03/22 21:53:04 obrien Exp $"); +#include "namespace.h" #include #include +#include "un-namespace.h" +#include "libc_private.h" #include "local.h" -/* Flush a single file, or (if fp is NULL) all files. */ +static int sflush_locked(FILE *); + +/* + * Flush a single file, or (if fp is NULL) all files. + * MT-safe version + */ int -fflush(fp) - register FILE *fp; +fflush(FILE *fp) { + int retval; if (fp == NULL) - return (_fwalk(__sflush)); + return (_fwalk(sflush_locked)); + FLOCKFILE(fp); if ((fp->_flags & (__SWR | __SRW)) == 0) { errno = EBADF; - return (EOF); - } - return (__sflush(fp)); + 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(fp) - register FILE *fp; +__sflush(FILE *fp) { - register unsigned char *p; - register int n, t; + unsigned char *p; + int n, t; t = fp->_flags; if ((t & __SWR) == 0) @@ -102,7 +112,7 @@ __sflush(fp) fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size; for (; n > 0; n -= t, p += t) { - t = (*fp->_write)(fp->_cookie, (char *)p, n); + t = _swrite(fp, (char *)p, n); if (t <= 0) { fp->_flags |= __SERR; return (EOF); @@ -110,3 +120,14 @@ __sflush(fp) } return (0); } + +static int +sflush_locked(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret = __sflush(fp); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/FreeBSD/fgetc.c b/stdio/FreeBSD/fgetc.c new file mode 100644 index 0000000..e3e0b47 --- /dev/null +++ b/stdio/FreeBSD/fgetc.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[] = "@(#)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.11 2002/08/13 09:30:41 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); + ORIENT(fp, -1); + retval = __sgetc(fp); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/fgetln.3 b/stdio/FreeBSD/fgetln.3 similarity index 100% rename from stdio/fgetln.3 rename to stdio/FreeBSD/fgetln.3 diff --git a/stdio/fgetln.c b/stdio/FreeBSD/fgetln.c similarity index 74% rename from stdio/fgetln.c rename to stdio/FreeBSD/fgetln.c index ffd203f..334e21d 100644 --- a/stdio/fgetln.c +++ b/stdio/FreeBSD/fgetln.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,10 +34,18 @@ * 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.8 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" /* @@ -71,10 +55,8 @@ * so we add 1 here. #endif */ -int -__slbexpand(fp, newsize) - FILE *fp; - size_t newsize; +static int +slbexpand(FILE *fp, size_t newsize) { void *p; @@ -98,23 +80,23 @@ __slbexpand(fp, newsize) * it if they wish. Thus, we set __SMOD in case the caller does. */ char * -fgetln(fp, lenp) - register FILE *fp; - size_t *lenp; +fgetln(FILE *fp, size_t *lenp) { - register unsigned char *p; - register size_t len; + unsigned char *p; + size_t len; size_t off; + FLOCKFILE(fp); /* 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', fp->_r)) != NULL) { - register char *ret; + if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) { + char *ret; /* * Found one. Flag buffer as modified to keep fseek from @@ -127,6 +109,7 @@ fgetln(fp, lenp) fp->_flags |= __SMOD; fp->_r -= len; fp->_p = p; + FUNLOCKFILE(fp); return (ret); } @@ -141,28 +124,28 @@ fgetln(fp, lenp) #define OPTIMISTIC 80 for (len = fp->_r, off = 0;; len += fp->_r) { - register size_t diff; + 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)) + 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', fp->_r)) == NULL) + 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)) + if (slbexpand(fp, len)) goto error; (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, diff); @@ -174,9 +157,11 @@ fgetln(fp, lenp) #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/FreeBSD/fgetpos.c b/stdio/FreeBSD/fgetpos.c new file mode 100644 index 0000000..581c5c8 --- /dev/null +++ b/stdio/FreeBSD/fgetpos.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.3 b/stdio/FreeBSD/fgets.3 similarity index 82% rename from stdio/fgets.3 rename to stdio/FreeBSD/fgets.3 index cb808a0..1b43d4c 100644 --- a/stdio/fgets.3 +++ b/stdio/FreeBSD/fgets.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fgets.3,v 1.12 2001/10/01 16:08:59 ru Exp $ +.\" $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 @@ -48,7 +48,7 @@ .Sh SYNOPSIS .In stdio.h .Ft char * -.Fn fgets "char *str" "int size" "FILE *stream" +.Fn fgets "char * restrict str" "int size" "FILE * restrict stream" .Ft char * .Fn gets "char *str" .Sh DESCRIPTION @@ -78,7 +78,7 @@ with an infinite and a .Fa stream of -.Em stdin , +.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. @@ -92,11 +92,11 @@ a pointer to the string. If end-of-file occurs before any characters are read, they return .Dv NULL -and the buffer contents is unchanged. +and the buffer contents remain unchanged. If an error occurs, they return .Dv NULL -and the buffer contents is indeterminate. +and the buffer contents are indeterminate. The .Fn fgets and @@ -132,27 +132,35 @@ 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 fgetln 3 , +.Xr fgetws 3 +.Rs +.%T "The FreeBSD Security Architecture" +.Re +(See +.Pa /usr/share/doc/{to be determined} . ) .Sh STANDARDS The functions .Fn fgets and .Fn gets conform to -.St -isoC . -.Sh BUGS -Since it is usually impossible to ensure that the next input line -is less than some arbitrary length, and because overflowing the -input buffer is almost invariably a security violation, programs -should -.Em NEVER -use -.Fn gets . -The -.Fn gets -function -exists purely to conform to -.St -isoC . +.St -isoC-99 . diff --git a/stdio/fgets.c b/stdio/FreeBSD/fgets.c similarity index 71% rename from stdio/fgets.c rename to stdio/FreeBSD/fgets.c index b14d3bf..36ae4fd 100644 --- a/stdio/fgets.c +++ b/stdio/FreeBSD/fgets.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,9 +34,18 @@ * 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. @@ -70,16 +55,18 @@ char * fgets(buf, n, fp) char *buf; - register int n; - register FILE *fp; + int n; + FILE *fp; { - register size_t len; - register char *s; - register unsigned char *p, *t; + size_t len; + char *s; + unsigned char *p, *t; - if (n == 0) /* sanity check */ + if (n <= 0) /* sanity check */ return (NULL); + FLOCKFILE(fp); + ORIENT(fp, -1); s = buf; n--; /* leave space for NUL */ while (n != 0) { @@ -89,8 +76,10 @@ fgets(buf, n, fp) if ((len = fp->_r) <= 0) { if (__srefill(fp)) { /* EOF/error: stop with partial or no line */ - if (s == buf) + if (s == buf) { + FUNLOCKFILE(fp); return (NULL); + } break; } len = fp->_r; @@ -112,6 +101,7 @@ fgets(buf, n, fp) fp->_p = t; (void)memcpy((void *)s, (void *)p, len); s[len] = 0; + FUNLOCKFILE(fp); return (buf); } fp->_r -= len; @@ -121,5 +111,6 @@ fgets(buf, n, fp) n -= len; } *s = 0; + FUNLOCKFILE(fp); return (buf); } diff --git a/stdio/FreeBSD/fgetwc.c b/stdio/FreeBSD/fgetwc.c new file mode 100644 index 0000000..0fc8f1d --- /dev/null +++ b/stdio/FreeBSD/fgetwc.c @@ -0,0 +1,109 @@ +/*- + * 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/fgetwc.c,v 1.6 2002/10/16 12:09:43 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +static __inline wint_t __fgetwc_nbf(FILE *); + +/* + * Non-MT-safe version. + */ +wint_t +__fgetwc(FILE *fp) +{ + wint_t wc; + + if (MB_CUR_MAX == 1) { + /* + * Assume we're using a single-byte locale. A safer test + * might be to check _CurrentRuneLocale->encoding. + */ + wc = (wint_t)__sgetc(fp); + } else + wc = __fgetwc_nbf(fp); + + return (wc); +} + +/* + * MT-safe version. + */ +wint_t +fgetwc(FILE *fp) +{ + wint_t r; + + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __fgetwc(fp); + FUNLOCKFILE(fp); + + return (r); +} + +static __inline wint_t +__fgetwc_nbf(FILE *fp) +{ + char buf[MB_LEN_MAX]; + mbstate_t mbs; + size_t n, nconv; + int c; + wchar_t wc; + + n = 0; + while (n < MB_CUR_MAX) { + if ((c = __sgetc(fp)) == EOF) { + if (n == 0) + return (WEOF); + break; + } + buf[n++] = (char)c; + memset(&mbs, 0, sizeof(mbs)); + nconv = mbrtowc(&wc, buf, n, &mbs); + if (nconv == n) + return (wc); + else if (nconv == 0) + return (L'\0'); + else if (nconv == (size_t)-1) + break; + } + + while (n-- != 0) + __ungetc((unsigned char)buf[n], fp); + errno = EILSEQ; + fp->_flags |= __SERR; + return (WEOF); +} diff --git a/stdio/FreeBSD/fgetws.3 b/stdio/FreeBSD/fgetws.3 new file mode 100644 index 0000000..ac51398 --- /dev/null +++ b/stdio/FreeBSD/fgetws.3 @@ -0,0 +1,125 @@ +.\" 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 +.Nd get a line of wide characters from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft "wchar_t *" +.Fn fgetws "wchar_t * restrict ws" "int n" "FILE * restrict fp" +.Sh DESCRIPTION +The +.Fn fgetws +function +reads at most one less than the number of characters specified by +.Fa n +from the given +.Fa fp +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. +.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, and 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 fp +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 +.Sh STANDARDS +The +.Fn fgetws +function +conforms to +.St -p1003.1-2001 . diff --git a/stdio/FreeBSD/fgetws.c b/stdio/FreeBSD/fgetws.c new file mode 100644 index 0000000..d818f62 --- /dev/null +++ b/stdio/FreeBSD/fgetws.c @@ -0,0 +1,75 @@ +/*- + * 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/fgetws.c,v 1.4 2002/09/20 13:25:40 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wchar_t * +fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) +{ + wchar_t *wsp; + wint_t wc; + + FLOCKFILE(fp); + ORIENT(fp, 1); + + if (n <= 0) { + errno = EINVAL; + goto error; + } + + wsp = ws; + while (n-- > 1) { + /* XXX Inefficient */ + if ((wc = __fgetwc(fp)) == WEOF && errno == EILSEQ) + goto error; + if (wc == WEOF) { + if (wsp == ws) + /* EOF/error, no characters read yet. */ + goto error; + break; + } + *wsp++ = (wchar_t)wc; + if (wc == L'\n') + break; + } + *wsp++ = L'\0'; + FUNLOCKFILE(fp); + + return (ws); + +error: + FUNLOCKFILE(fp); + return (NULL); +} diff --git a/stdio/FreeBSD/fileno.c b/stdio/FreeBSD/fileno.c new file mode 100644 index 0000000..6e4b0a8 --- /dev/null +++ b/stdio/FreeBSD/fileno.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[] = "@(#)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.9 2003/01/13 02:58:18 tjr Exp $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* + * fileno has traditionally been a macro in . That is + * no longer true because it needs to be thread-safe. + * + * #undef fileno + */ +int +fileno(FILE *fp) +{ + int fd; + + FLOCKFILE(fp); + fd = __sfileno(fp); + FUNLOCKFILE(fp); + + return (fd); +} diff --git a/stdio/findfp.c b/stdio/FreeBSD/findfp.c similarity index 53% rename from stdio/findfp.c rename to stdio/FreeBSD/findfp.c index 9b50618..a90f74a 100644 --- a/stdio/findfp.c +++ b/stdio/FreeBSD/findfp.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,52 +34,104 @@ * 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.28 2002/11/14 14:06:14 imp Exp $"); #include +#include #include #include -#include #include #include + +#include + +#include "libc_private.h" #include "local.h" #include "glue.h" -int __sdidinit = 0; +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} -/* p r w flags file _bf z cookie close read seek write */ - + {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 */ /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; -static struct glue uglue = { 0, FOPEN_MAX - 3, usual }; +static struct __sFILEX usual_extra[FOPEN_MAX - 3]; +static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; +static struct __sFILEX __sFX[3]; + +/* + * We can't make this 'static' until 6.0-current due to binary + * compatibility concerns. This also means we cannot change the + * sizeof(FILE) until that time either and must continue to use the + * __sFILEX stuff to add to FILE. + */ FILE __sF[3] = { - std(__SRD, STDIN_FILENO), /* stdin */ - std(__SWR, STDOUT_FILENO), /* stdout */ - std(__SWR|__SNBF, STDERR_FILENO) /* stderr */ + 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) - register int n; + int n; { - register struct glue *g; - register FILE *p; + struct glue *g; static FILE empty; + static struct __sFILEX emptyx; + FILE *p; + struct __sFILEX *fx; - g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)); + g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + + n * sizeof(struct __sFILEX)); if (g == NULL) return (NULL); p = (FILE *)ALIGN(g + 1); + fx = (struct __sFILEX *)&p[n]; g->next = NULL; g->niobs = n; g->iobs = p; - while (--n >= 0) - *p++ = empty; + while (--n >= 0) { + *p = empty; + p->_extra = fx; + *p->_extra = emptyx; + p++, fx++; + } return (g); } @@ -113,22 +141,31 @@ moreglue(n) FILE * __sfp() { - register FILE *fp; - register int n; - register struct glue *g; + FILE *fp; + int n; + struct glue *g; if (!__sdidinit) __sinit(); - for (g = &__sglue;; g = g->next) { + /* + * 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; - if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL) - break; } - return (NULL); + 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; @@ -141,6 +178,13 @@ found: 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->orientation = 0; +#ifdef notdef + /* Stateful encoding/decoding is not yet supported. */ + memset(&fp->_extra->wstate, 0, sizeof(mbstate_t)); + memset(&fp->_extra->rstate, 0, sizeof(mbstate_t)); +#endif return (fp); } @@ -148,17 +192,29 @@ found: * 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() { - register struct glue *g; + 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->next = moreglue(n); + if ((n > 0) && ((g = moreglue(n)) != NULL)) { + THREAD_LOCK(); + SET_GLUE_PTR(lastglue->next, g); + lastglue = g; + THREAD_UNLOCK(); + } } /* @@ -181,7 +237,17 @@ _cleanup() void __sinit() { - /* make sure we clean up on exit */ - __cleanup = _cleanup; /* conservative */ - __sdidinit = 1; + 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/FreeBSD/findfp.c.patch b/stdio/FreeBSD/findfp.c.patch new file mode 100644 index 0000000..b971a9c --- /dev/null +++ b/stdio/FreeBSD/findfp.c.patch @@ -0,0 +1,60 @@ +--- findfp.c.orig Tue May 20 15:22:41 2003 ++++ findfp.c Sun Jul 20 18:50:26 2003 +@@ -47,6 +47,7 @@ + #include + #include + ++#include + #include + + #include "libc_private.h" +@@ -62,12 +63,13 @@ + {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]; ++static struct __sFILEX __sFX[3] = {__sFXInit, __sFXInit, __sFXInit}; + + /* + * We can't make this 'static' until 6.0-current due to binary +@@ -81,17 +83,6 @@ + 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; + +@@ -113,7 +104,7 @@ + { + struct glue *g; + static FILE empty; +- static struct __sFILEX emptyx; ++ static struct __sFILEX emptyx = __sFXInit; + FILE *p; + struct __sFILEX *fx; + +@@ -179,6 +170,7 @@ + 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; + #ifdef notdef + /* Stateful encoding/decoding is not yet supported. */ diff --git a/stdio/flags.c b/stdio/FreeBSD/flags.c similarity index 69% rename from stdio/flags.c rename to stdio/FreeBSD/flags.c index 89405a1..cd90f83 100644 --- a/stdio/flags.c +++ b/stdio/FreeBSD/flags.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,23 +34,30 @@ * 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. + * to be passed to an _open() syscall through *optr. * Return 0 on error. */ int __sflags(mode, optr) - register char *mode; + const char *mode; int *optr; { - register int ret, m, o; + int ret, m, o; switch (*mode++) { diff --git a/stdio/FreeBSD/floatio.h b/stdio/FreeBSD/floatio.h new file mode 100644 index 0000000..8f7902f --- /dev/null +++ b/stdio/FreeBSD/floatio.h @@ -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. + * + * @(#)floatio.h 8.1 (Berkeley) 6/4/93 + * $FreeBSD: src/lib/libc/stdio/floatio.h,v 1.4 2003/04/05 22:11:42 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 *__ldtoa(long double *, int, int, int *, int *, char **); diff --git a/stdio/FreeBSD/flockfile.3 b/stdio/FreeBSD/flockfile.3 new file mode 100644 index 0000000..a8c9c26 --- /dev/null +++ b/stdio/FreeBSD/flockfile.3 @@ -0,0 +1,104 @@ +.\" 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 *stream" +.Ft int +.Fn ftrylockfile "FILE *stream" +.Ft void +.Fn funlockfile "FILE *stream" +.Sh DESCRIPTION +These functions provide explicit application-level locking of stdio streams. +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. +.Pp +The +.Fn flockfile +function acquires an exclusive lock on the specified stream. +If another thread has already locked the stream, +.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 a stream 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. +Each time +.Fn flockfile +is called on the stream, the count is incremented, +and each time +.Fn funlockfile +is called on the stream, 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 stream 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.3 b/stdio/FreeBSD/fopen.3 similarity index 87% rename from stdio/fopen.3 rename to stdio/FreeBSD/fopen.3 index cbf6234..a328c5b 100644 --- a/stdio/fopen.3 +++ b/stdio/FreeBSD/fopen.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)fopen.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.12 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.18 2003/01/26 10:01:59 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd January 26, 2003 .Dt FOPEN 3 .Os .Sh NAME @@ -49,7 +49,7 @@ .Sh SYNOPSIS .In stdio.h .Ft FILE * -.Fn fopen "const char *path" "const char *mode" +.Fn fopen "const char * restrict path" "const char * restrict mode" .Ft FILE * .Fn fdopen "int fildes" "const char *mode" .Ft FILE * @@ -137,8 +137,7 @@ The .Fn fdopen function associates a stream with the existing file descriptor, .Fa fildes . -The -.Fa mode +The mode of the stream must be compatible with the mode of the file descriptor. When the stream is closed via .Xr fclose 3 , @@ -159,15 +158,49 @@ The argument is used just as in the .Fn fopen function. +.Pp +If the +.Fa path +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 -.Pf ( Em stderr , -.Em stdin , +.Dv ( stderr , stdin , or -.Em stdout ) . +.Dv stdout ) . .Sh RETURN VALUES Upon successful completion .Fn fopen , @@ -187,7 +220,8 @@ is set to indicate the error. .It Bq Er EINVAL The .Fa mode -provided to +argument +to .Fn fopen , .Fn fdopen , or @@ -235,6 +269,7 @@ and .Sh SEE ALSO .Xr open 2 , .Xr fclose 3 , +.Xr fileno 3 , .Xr fseek 3 , .Xr funopen 3 .Sh STANDARDS diff --git a/stdio/fopen.c b/stdio/FreeBSD/fopen.c similarity index 69% rename from stdio/fopen.c rename to stdio/FreeBSD/fopen.c index d735260..5a043ca 100644 --- a/stdio/fopen.c +++ b/stdio/FreeBSD/fopen.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,28 +34,36 @@ * 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 *file; - const char *mode; + const char * __restrict file; + const char * __restrict mode; { - register FILE *fp; - register int f; + 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) { + if ((f = _open(file, oflags, DEFFILEMODE)) < 0) { fp->_flags = 0; /* release */ return (NULL); } @@ -90,7 +74,6 @@ fopen(file, mode) 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 @@ -100,6 +83,6 @@ fopen(file, mode) * fseek and ftell.) */ if (oflags & O_APPEND) - (void) __sseek((void *)fp, (fpos_t)0, SEEK_END); + (void)_sseek(fp, (fpos_t)0, SEEK_END); return (fp); } diff --git a/stdio/FreeBSD/fprintf.c b/stdio/FreeBSD/fprintf.c new file mode 100644 index 0000000..35093b0 --- /dev/null +++ b/stdio/FreeBSD/fprintf.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[] = "@(#)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 +#include + +int +fprintf(FILE * __restrict fp, const char * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(fp, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/stdio/FreeBSD/fpurge.c b/stdio/FreeBSD/fpurge.c new file mode 100644 index 0000000..f191843 --- /dev/null +++ b/stdio/FreeBSD/fpurge.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.c b/stdio/FreeBSD/fputc.c similarity index 64% rename from stdio/fputc.c rename to stdio/FreeBSD/fputc.c index 4a23f9c..4aac5ef 100644 --- a/stdio/fputc.c +++ b/stdio/FreeBSD/fputc.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,27 @@ * 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.11 2002/08/13 09:30:41 tjr Exp $"); +#include "namespace.h" #include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" int fputc(c, fp) int c; - register FILE *fp; + FILE *fp; { - return (putc(c, fp)); + int retval; + FLOCKFILE(fp); + ORIENT(fp, -1); + retval = putc(c, fp); + FUNLOCKFILE(fp); + return (retval); } diff --git a/stdio/fputs.3 b/stdio/FreeBSD/fputs.3 similarity index 96% rename from stdio/fputs.3 rename to stdio/FreeBSD/fputs.3 index 4702017..a0c0341 100644 --- a/stdio/fputs.3 +++ b/stdio/FreeBSD/fputs.3 @@ -34,7 +34,7 @@ .\" 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/fputs.3,v 1.11 2002/12/19 09:40:24 ru Exp $ .\" .Dd June 4, 1993 .Dt FPUTS 3 @@ -68,7 +68,7 @@ writes the string .Fa str , and a terminating newline character, to the stream -.Em stdout . +.Dv stdout . .Sh RETURN VALUES The .Fn fputs @@ -85,7 +85,7 @@ on error. .It Bq Er EBADF The .Fa stream -supplied +argument is not a writable stream. .El .Pp @@ -99,6 +99,7 @@ for any of the errors specified for the routines .Xr write 2 . .Sh SEE ALSO .Xr ferror 3 , +.Xr fputws 3 , .Xr putc 3 , .Xr stdio 3 .Sh STANDARDS diff --git a/stdio/FreeBSD/fputs.3.patch b/stdio/FreeBSD/fputs.3.patch new file mode 100644 index 0000000..174daab --- /dev/null +++ b/stdio/FreeBSD/fputs.3.patch @@ -0,0 +1,16 @@ +--- fputs.3.orig Tue May 20 15:22:42 2003 ++++ fputs.3 Thu Jul 31 17:34:11 2003 +@@ -109,3 +109,13 @@ + .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/fputs.c b/stdio/FreeBSD/fputs.c similarity index 66% rename from stdio/fputs.c rename to stdio/FreeBSD/fputs.c index dc20aaa..58278ab 100644 --- a/stdio/fputs.c +++ b/stdio/FreeBSD/fputs.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,19 +34,29 @@ * 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" /* * Write the given string to the given file. */ int fputs(s, fp) - const char *s; - FILE *fp; + const char * __restrict s; + FILE * __restrict fp; { + int retval; struct __suio uio; struct __siov iov; @@ -78,5 +64,9 @@ fputs(s, fp) iov.iov_len = uio.uio_resid = strlen(s); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - return (__sfvwrite(fp, &uio)); + FLOCKFILE(fp); + ORIENT(fp, -1); + retval = __sfvwrite(fp, &uio); + FUNLOCKFILE(fp); + return (retval); } diff --git a/stdio/FreeBSD/fputs.c.patch b/stdio/FreeBSD/fputs.c.patch new file mode 100644 index 0000000..19dee98 --- /dev/null +++ b/stdio/FreeBSD/fputs.c.patch @@ -0,0 +1,22 @@ +--- fputs.c.orig Tue May 20 15:22:42 2003 ++++ fputs.c Thu Jul 31 13:19:02 2003 +@@ -48,6 +48,9 @@ + #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. + */ +@@ -60,6 +63,9 @@ + 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; diff --git a/stdio/FreeBSD/fputwc.c b/stdio/FreeBSD/fputwc.c new file mode 100644 index 0000000..55b02fa --- /dev/null +++ b/stdio/FreeBSD/fputwc.c @@ -0,0 +1,87 @@ +/*- + * 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/fputwc.c,v 1.5 2002/10/16 12:09:43 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Non-MT-safe version. + */ +wint_t +__fputwc(wchar_t wc, FILE *fp) +{ + char buf[MB_LEN_MAX]; + mbstate_t mbs; + size_t i, len; + + if (MB_LEN_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 { + memset(&mbs, 0, sizeof(mbs)); + if ((len = wcrtomb(buf, wc, &mbs)) == (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); + FUNLOCKFILE(fp); + + return (r); +} diff --git a/string/strcat.3 b/stdio/FreeBSD/fputws.3 similarity index 70% rename from string/strcat.3 rename to stdio/FreeBSD/fputws.3 index e6e9b51..2642a74 100644 --- a/string/strcat.3 +++ b/stdio/FreeBSD/fputws.3 @@ -33,69 +33,60 @@ .\" 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.9 2001/10/01 16:09:00 ru Exp $ +.\" @(#)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 June 4, 1993 -.Dt STRCAT 3 +.Dd August 6, 2002 +.Dt FPUTWS 3 .Os .Sh NAME -.Nm strcat -.Nd concatenate strings +.Nm fputws +.Nd output a line of wide characters to a stream .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h -.Ft char * -.Fn strcat "char *s" "const char *append" -.Ft char * -.Fn strncat "char *s" "const char *append" "size_t count" +.In stdio.h +.In wchar.h +.Ft int +.Fn fputws "const wchar_t * restrict ws" "FILE * restrict fp" .Sh DESCRIPTION The -.Fn strcat -and -.Fn strncat -functions -append a copy of the null-terminated string -.Fa append -to the end of the null-terminated string -.Fa s , -then add a terminating -.Ql \e0 . -The string -.Fa s -must have sufficient space to hold the result. -.Pp +.Fn fputws +function writes the wide character string pointed to by +.Fa ws +to the stream pointed to by +.Fa fp . +.Sh RETURN VALUES The -.Fn strncat +.Fn fputws function -appends not more than -.Fa count -characters from -.Fa append , -and then adds a terminating -.Ql \e0 . -.Sh RETURN VALUES +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 fp +argument supplied +is not a writable stream. +.El +.Pp The -.Fn strcat -and -.Fn strncat -functions -return the pointer -.Fa s . +.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 bcopy 3 , -.Xr memccpy 3 , -.Xr memcpy 3 , -.Xr memmove 3 , -.Xr strcpy 3 , -.Xr strlcat 3 , -.Xr strlcpy 3 +.Xr ferror 3 , +.Xr fputs 3 , +.Xr putwc 3 , +.Xr stdio 3 .Sh STANDARDS The -.Fn strcat -and -.Fn strncat -functions -conform to -.St -isoC . +.Fn fputws +function conforms to +.St -p1003.1-2001 . diff --git a/stdio/FreeBSD/fputws.c b/stdio/FreeBSD/fputws.c new file mode 100644 index 0000000..b1eb8ed --- /dev/null +++ b/stdio/FreeBSD/fputws.c @@ -0,0 +1,53 @@ +/*- + * 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/fputws.c,v 1.4 2002/09/20 13:25:40 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fputws(const wchar_t * __restrict ws, FILE * __restrict fp) +{ + + FLOCKFILE(fp); + ORIENT(fp, 1); + /* XXX Inefficient */ + while (*ws != '\0') + if (__fputwc(*ws++, fp) == WEOF) { + FUNLOCKFILE(fp); + return (-1); + } + FUNLOCKFILE(fp); + + return (0); +} diff --git a/stdio/fread.3 b/stdio/FreeBSD/fread.3 similarity index 92% rename from stdio/fread.3 rename to stdio/FreeBSD/fread.3 index 16cebfc..b0bf094 100644 --- a/stdio/fread.3 +++ b/stdio/FreeBSD/fread.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)fread.3 8.2 (Berkeley) 3/8/94 -.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.8 2001/10/01 16:08:59 ru Exp $ +.\" $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 @@ -48,9 +48,9 @@ .Sh SYNOPSIS .In stdio.h .Ft size_t -.Fn fread "void *ptr" "size_t size" "size_t nmemb" "FILE *stream" +.Fn fread "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream" .Ft size_t -.Fn fwrite "const void *ptr" "size_t size" "size_t nmemb" "FILE *stream" +.Fn fwrite "const void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream" .Sh DESCRIPTION The function .Fn fread diff --git a/stdio/fread.c b/stdio/FreeBSD/fread.c similarity index 70% rename from stdio/fread.c rename to stdio/FreeBSD/fread.c index c6fade3..ad5d81b 100644 --- a/stdio/fread.c +++ b/stdio/FreeBSD/fread.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,19 +34,28 @@ * 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 *buf; + void * __restrict buf; size_t size, count; - register FILE *fp; + FILE * __restrict fp; { - register size_t resid; - register char *p; - register int r; + size_t resid; + char *p; + int r; size_t total; /* @@ -80,6 +65,8 @@ fread(buf, size, count, fp) */ if ((resid = count * size) == 0) return (0); + FLOCKFILE(fp); + ORIENT(fp, -1); if (fp->_r < 0) fp->_r = 0; total = resid; @@ -92,11 +79,13 @@ fread(buf, size, count, fp) resid -= r; if (__srefill(fp)) { /* no more input: return partial result */ + FUNLOCKFILE(fp); return ((total - resid) / size); } } (void)memcpy((void *)p, (void *)fp->_p, resid); fp->_r -= resid; fp->_p += resid; + FUNLOCKFILE(fp); return (count); } diff --git a/stdio/freopen.c b/stdio/FreeBSD/freopen.c similarity index 70% rename from stdio/freopen.c rename to stdio/FreeBSD/freopen.c index 7f94eec..4412ef8 100644 --- a/stdio/freopen.c +++ b/stdio/FreeBSD/freopen.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,7 +34,13 @@ * 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.12 2003/01/26 11:45:54 tjr Exp $"); +#include "namespace.h" #include #include #include @@ -66,29 +48,87 @@ #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. +/* + * 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 *file, *mode; - register FILE *fp; + const char * __restrict file; + const char * __restrict mode; + FILE *fp; { - register int f; - int flags, isopen, oflags, sverrno, wantfd; + 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 = EINVAL; + 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. @@ -114,17 +154,18 @@ freopen(file, mode, fp) } /* Get a new descriptor to refer to the new file. */ - f = open(file, oflags, DEFFILEMODE); + 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); + 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 @@ -146,10 +187,12 @@ freopen(file, mode, fp) if (HASLB(fp)) FREELB(fp); fp->_lb._size = 0; + fp->_extra->orientation = 0; 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); } @@ -159,8 +202,8 @@ freopen(file, mode, fp) * 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); + if (_dup2(f, wantfd) >= 0) { + (void)_close(f); f = wantfd; } } @@ -172,5 +215,6 @@ freopen(file, mode, fp) fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; + FUNLOCKFILE(fp); return (fp); } diff --git a/stdio/FreeBSD/fscanf.c b/stdio/FreeBSD/fscanf.c new file mode 100644 index 0000000..aaad500 --- /dev/null +++ b/stdio/FreeBSD/fscanf.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[] = "@(#)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 "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(fp, fmt, ap); + va_end(ap); + FUNLOCKFILE(fp); + return (ret); +} diff --git a/stdio/fseek.3 b/stdio/FreeBSD/fseek.3 similarity index 92% rename from stdio/fseek.3 rename to stdio/FreeBSD/fseek.3 index 7343c96..8c78ce7 100644 --- a/stdio/fseek.3 +++ b/stdio/FreeBSD/fseek.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)fseek.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.19 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.24 2002/12/19 09:40:24 ru Exp $ .\" -.Dd March 5, 1999 +.Dd October 12, 2002 .Dt FSEEK 3 .Os .Sh NAME @@ -59,7 +59,7 @@ .Ft void .Fn rewind "FILE *stream" .Ft int -.Fn fgetpos "FILE *stream" "fpos_t *pos" +.Fn fgetpos "FILE * restrict stream" "fpos_t * restrict pos" .Ft int .Fn fsetpos "FILE *stream" "const fpos_t *pos" .In sys/types.h @@ -92,7 +92,9 @@ A successful call to the function clears the end-of-file indicator for the stream and undoes any effects of the .Xr ungetc 3 -function on the same stream. +and +.Xr ungetwc 3 +functions on the same stream. .Pp The .Fn ftell @@ -162,6 +164,14 @@ systems an .Dq Fa fpos_t object may be a complex object and these routines may be the only way to portably reposition a text stream. +.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 @@ -183,7 +193,7 @@ is set to indicate the error. .It Bq Er EBADF The .Fa stream -specified +argument is not a seekable stream. .It Bq Er EINVAL The @@ -231,7 +241,9 @@ and .Sh SEE ALSO .Xr lseek 2 , .Xr clearerr 3 , -.Xr ungetc 3 +.Xr fwide 3 , +.Xr ungetc 3 , +.Xr ungetwc 3 .Sh STANDARDS The .Fn fgetpos , @@ -249,4 +261,4 @@ The and .Fn ftello functions conform to -.St -susv2 . +.St -p1003.1-2001 . diff --git a/stdio/fseek.c b/stdio/FreeBSD/fseek.c similarity index 68% rename from stdio/fseek.c rename to stdio/FreeBSD/fseek.c index bc9cc57..3ff409b 100644 --- a/stdio/fseek.c +++ b/stdio/FreeBSD/fseek.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,56 +34,91 @@ * 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.40 2002/03/22 21:53:04 obrien Exp $"); -#include +#include "namespace.h" #include #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) - register FILE *fp; + FILE *fp; long offset; int whence; { - return (fseeko(fp, offset, 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) - register FILE *fp; +_fseeko(fp, offset, whence, ltest) + FILE *fp; off_t offset; int whence; + int ltest; { - register fpos_t (*seekfn) __P((void *, fpos_t, int)); - fpos_t target, curoff; + fpos_t (*seekfn)(void *, fpos_t, int); + fpos_t target, curoff, ret; size_t n; struct stat st; int havepos; - /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); - - /* FLOCKFILE(fp); */ /* * Have to be able to seek. */ if ((seekfn = fp->_seek) == NULL) { - errno = ESPIPE; /* historic practice */ - /* FUNLOCKFILE(fp); */ - return (EOF); + errno = ESPIPE; /* historic practice */ + return (-1); } /* @@ -119,31 +130,38 @@ fseeko(fp, offset, whence) case SEEK_CUR: /* * In order to seek relative to the current stream offset, - * we have to first find the current stream offset a la + * we have to first find the current stream offset via * ftell (see ftell for details). */ - if (fp->_flags & __SOFF) - curoff = fp->_offset; - else { - curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (curoff == -1) { - /* FUNLOCKFILE(fp); */ - return (EOF); - } + 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); } - if (fp->_flags & __SRD) { - curoff -= fp->_r; - if (HASUB(fp)) - curoff -= fp->_ur; - } else if (fp->_flags & __SWR && fp->_p != NULL) - curoff += fp->_p - fp->_bf._base; - 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; @@ -151,8 +169,7 @@ fseeko(fp, offset, whence) default: errno = EINVAL; - /* FUNLOCKFILE(fp); */ - return (EOF); + return (-1); } /* @@ -169,7 +186,7 @@ fseeko(fp, offset, whence) goto dumb; if ((fp->_flags & __SOPT) == 0) { if (seekfn != __sseek || - fp->_file < 0 || fstat(fp->_file, &st) || + fp->_file < 0 || _fstat(fp->_file, &st) || (st.st_mode & S_IFMT) != S_IFREG) { fp->_flags |= __SNPT; goto dumb; @@ -185,24 +202,33 @@ fseeko(fp, offset, whence) if (whence == SEEK_SET) target = offset; else { - if (fstat(fp->_file, &st)) + 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 (!havepos) { - if (fp->_flags & __SOFF) - curoff = fp->_offset; - else { - curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (curoff == POS_ERR) - goto dumb; + if ((off_t)target < 0) { + errno = EINVAL; + return (-1); + } + if (ltest && (off_t)target > LONG_MAX) { + errno = EOVERFLOW; + return (-1); } - curoff -= fp->_r; - if (HASUB(fp)) - curoff -= fp->_ur; } + 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 @@ -211,7 +237,7 @@ fseeko(fp, offset, whence) */ if (HASUB(fp)) { curoff += fp->_r; /* kill off ungetc */ - n = fp->_up - fp->_bf._base; + n = fp->_extra->_up - fp->_bf._base; curoff -= n; n += fp->_ur; } else { @@ -223,22 +249,20 @@ fseeko(fp, offset, whence) /* * If the target offset is within the current buffer, * simply adjust the pointers, clear EOF, undo ungetc(), - * and return. (If the buffer was modified, we have to - * skip this; see fgetln.c.) + * and return. */ - if ((fp->_flags & __SMOD) == 0 && - target >= curoff && target < curoff + n) { - register int o = target - curoff; + 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; - /* FUNLOCKFILE(fp); */ 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. @@ -248,13 +272,12 @@ fseeko(fp, offset, whence) * ensures that we only read one block, rather than two. */ curoff = target & ~(fp->_blksize - 1); - if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) == POS_ERR) + if (_sseek(fp, curoff, SEEK_SET) == POS_ERR) goto dumb; fp->_r = 0; fp->_p = fp->_bf._base; if (HASUB(fp)) FREEUB(fp); - fp->_flags &= ~__SEOF; n = target - curoff; if (n) { if (__srefill(fp) || fp->_r < n) @@ -262,7 +285,7 @@ fseeko(fp, offset, whence) fp->_p += n; fp->_r -= n; } - /* FUNLOCKFILE(fp); */ + fp->_flags &= ~__SEOF; return (0); /* @@ -271,10 +294,8 @@ fseeko(fp, offset, whence) */ dumb: if (__sflush(fp) || - (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) { - /* FUNLOCKFILE(fp); */ - return (EOF); - } + (ret = _sseek(fp, (fpos_t)offset, whence)) == POS_ERR) + return (-1); /* success: clear EOF indicator and discard ungetc() data */ if (HASUB(fp)) FREEUB(fp); @@ -282,6 +303,10 @@ dumb: fp->_r = 0; /* fp->_w = 0; */ /* unnecessary (I think...) */ fp->_flags &= ~__SEOF; - /* FUNLOCKFILE(fp); */ + if (ltest && ret > LONG_MAX) { + fp->_flags |= __SERR; + errno = EOVERFLOW; + return (-1); + } return (0); } diff --git a/stdio/fsetpos.c b/stdio/FreeBSD/fsetpos.c similarity index 66% rename from stdio/fsetpos.c rename to stdio/FreeBSD/fsetpos.c index bd3f47c..6d75acd 100644 --- a/stdio/fsetpos.c +++ b/stdio/FreeBSD/fsetpos.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,6 +34,12 @@ * 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 diff --git a/stdio/ftell.c b/stdio/FreeBSD/ftell.c similarity index 62% rename from stdio/ftell.c rename to stdio/FreeBSD/ftell.c index 260f47e..477e3a1 100644 --- a/stdio/ftell.c +++ b/stdio/FreeBSD/ftell.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,27 +34,73 @@ * 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 +#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) - register FILE *fp; + FILE *fp; { - register fpos_t pos; + 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 (-1L); + return (1); } - /* FLOCKFILE(fp); */ /* * Find offset of underlying I/O object, then * adjust for buffered bytes. @@ -86,11 +108,9 @@ ftello(fp) if (fp->_flags & __SOFF) pos = fp->_offset; else { - pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (pos == -1) { - /* FUNLOCKFILE(fp); */ - return (pos); - } + pos = _sseek(fp, (fpos_t)0, SEEK_CUR); + if (pos == -1) + return (1); } if (fp->_flags & __SRD) { /* @@ -98,33 +118,26 @@ ftello(fp) * those from ungetc) cause the position to be * smaller than that in the underlying object. */ - pos -= fp->_r; + if ((pos -= (HASUB(fp) ? fp->_ur : fp->_r)) < 0) { + fp->_flags |= __SERR; + errno = EIO; + return (1); + } if (HASUB(fp)) - pos -= fp->_ur; - } else if (fp->_flags & __SWR && fp->_p != NULL) { + 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. */ - pos += fp->_p - fp->_bf._base; + n = fp->_p - fp->_bf._base; + if (pos > OFF_MAX - n) { + errno = EOVERFLOW; + return (1); + } + pos += n; } - /* FUNLOCKFILE(fp); */ - return (pos); -} - -/* - * standard ftell function. - */ -long -ftell(fp) - register FILE *fp; -{ - register off_t rv; - rv = ftello(fp); - if ((long)rv != rv) { - errno = EOVERFLOW; - return (-1); - } - return (rv); + *offset = pos; + return (0); } diff --git a/stdio/funopen.3 b/stdio/FreeBSD/funopen.3 similarity index 100% rename from stdio/funopen.3 rename to stdio/FreeBSD/funopen.3 diff --git a/stdio/funopen.c b/stdio/FreeBSD/funopen.c similarity index 70% rename from stdio/funopen.c rename to stdio/FreeBSD/funopen.c index 9840104..040c806 100644 --- a/stdio/funopen.c +++ b/stdio/FreeBSD/funopen.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,23 +34,25 @@ * 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)(); -#if __STDC__ fpos_t (*seekfn)(void *cookie, fpos_t off, int whence); -#else - fpos_t (*seekfn)(); -#endif int (*closefn)(); { - register FILE *fp; + FILE *fp; int flags; if (readfn == NULL) { diff --git a/stdio/fvwrite.c b/stdio/FreeBSD/fvwrite.c similarity index 92% rename from stdio/fvwrite.c rename to stdio/FreeBSD/fvwrite.c index b316854..80057ac 100644 --- a/stdio/fvwrite.c +++ b/stdio/FreeBSD/fvwrite.c @@ -35,12 +35,10 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -#if 0 static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.10 1999/08/28 00:01:06 peter Exp $"; #endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.15 2002/03/22 21:53:04 obrien Exp $"); #include #include @@ -56,13 +54,13 @@ static const char rcsid[] = */ int __sfvwrite(fp, uio) - register FILE *fp; - register struct __suio *uio; + FILE *fp; + struct __suio *uio; { - register size_t len; - register char *p; - register struct __siov *iov; - register int w, s; + size_t len; + char *p; + struct __siov *iov; + int w, s; char *nl; int nlknown, nldist; @@ -92,7 +90,7 @@ __sfvwrite(fp, uio) */ do { GETIOV(;); - w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ)); + w = _swrite(fp, p, MIN(len, BUFSIZ)); if (w <= 0) goto err; p += w; @@ -143,11 +141,11 @@ __sfvwrite(fp, uio) COPY(w); /* fp->_w -= w; */ /* unneeded */ fp->_p += w; - if (fflush(fp)) + if (__fflush(fp)) goto err; } else if (len >= (w = fp->_bf._size)) { /* write directly */ - w = (*fp->_write)(fp->_cookie, p, w); + w = _swrite(fp, p, w); if (w <= 0) goto err; } else { @@ -183,10 +181,10 @@ __sfvwrite(fp, uio) COPY(w); /* fp->_w -= w; */ fp->_p += w; - if (fflush(fp)) + if (__fflush(fp)) goto err; } else if (s >= (w = fp->_bf._size)) { - w = (*fp->_write)(fp->_cookie, p, w); + w = _swrite(fp, p, w); if (w <= 0) goto err; } else { @@ -197,7 +195,7 @@ __sfvwrite(fp, uio) } if ((nldist -= w) == 0) { /* copied the newline: flush and forget */ - if (fflush(fp)) + if (__fflush(fp)) goto err; nlknown = 0; } diff --git a/stdio/fvwrite.h b/stdio/FreeBSD/fvwrite.h similarity index 96% rename from stdio/fvwrite.h rename to stdio/FreeBSD/fvwrite.h index ec6bc0b..5414ec8 100644 --- a/stdio/fvwrite.h +++ b/stdio/FreeBSD/fvwrite.h @@ -34,6 +34,7 @@ * SUCH DAMAGE. * * @(#)fvwrite.h 8.1 (Berkeley) 6/4/93 + * $FreeBSD: src/lib/libc/stdio/fvwrite.h,v 1.3 2002/05/28 16:59:39 alfred Exp $ */ /* @@ -49,8 +50,4 @@ struct __suio { int uio_resid; }; -#if __STDC__ || c_plusplus extern int __sfvwrite(FILE *, struct __suio *); -#else -extern int __sfvwrite(); -#endif diff --git a/stdlib/rand.c b/stdio/FreeBSD/fwalk.c similarity index 64% rename from stdlib/rand.c rename to stdio/FreeBSD/fwalk.c index 42a5bd4..a8a49fc 100644 --- a/stdlib/rand.c +++ b/stdio/FreeBSD/fwalk.c @@ -2,6 +2,9 @@ * 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: @@ -29,79 +32,40 @@ * LIABILITY, OR TORT (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 . - * - * $FreeBSD: src/lib/libc/stdlib/rand.c,v 1.2.2.1 2001/03/05 11:33:57 obrien Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93"; +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 - -#ifdef TEST +#include #include -#endif /* TEST */ - -static int -do_rand(unsigned long *ctx) -{ - return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); -} - - -int -rand_r(unsigned int *ctx) -{ - u_long val = (u_long) *ctx; - *ctx = do_rand(&val); - return (int) *ctx; -} - - -static u_long next = 1; +#include "local.h" +#include "glue.h" int -rand() +_fwalk(function) + int (*function)(FILE *); { - return do_rand(&next); + 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); } - -void -srand(seed) -u_int seed; -{ - next = seed; -} - -#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/stdio/FreeBSD/fwide.3 b/stdio/FreeBSD/fwide.3 new file mode 100644 index 0000000..1c1961f --- /dev/null +++ b/stdio/FreeBSD/fwide.3 @@ -0,0 +1,97 @@ +.\" $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 byte-oriented. +If it is greater than zero, +.Fa stream +is set to 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/FreeBSD/fwide.c b/stdio/FreeBSD/fwide.c new file mode 100644 index 0000000..1386c48 --- /dev/null +++ b/stdio/FreeBSD/fwide.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/FreeBSD/fwprintf.c b/stdio/FreeBSD/fwprintf.c new file mode 100644 index 0000000..dcd6c38 --- /dev/null +++ b/stdio/FreeBSD/fwprintf.c @@ -0,0 +1,45 @@ +/*- + * 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 +#include +#include + +int +fwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfwprintf(fp, fmt, ap); + va_end(ap); + + return (ret); +} diff --git a/stdio/fwrite.c b/stdio/FreeBSD/fwrite.c similarity index 68% rename from stdio/fwrite.c rename to stdio/FreeBSD/fwrite.c index 8948990..27b660e 100644 --- a/stdio/fwrite.c +++ b/stdio/FreeBSD/fwrite.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,10 +34,18 @@ * 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. @@ -69,9 +53,9 @@ */ size_t fwrite(buf, size, count, fp) - const void *buf; + const void * __restrict buf; size_t size, count; - FILE *fp; + FILE * __restrict fp; { size_t n; struct __suio uio; @@ -82,12 +66,15 @@ fwrite(buf, size, count, fp) 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) - return (count); - return ((n - uio.uio_resid) / size); + if (__sfvwrite(fp, &uio) != 0) + count = (n - uio.uio_resid) / size; + FUNLOCKFILE(fp); + return (count); } diff --git a/stdio/FreeBSD/fwscanf.c b/stdio/FreeBSD/fwscanf.c new file mode 100644 index 0000000..47e8550 --- /dev/null +++ b/stdio/FreeBSD/fwscanf.c @@ -0,0 +1,45 @@ +/*- + * 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 +#include +#include + +int +fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = vfwscanf(fp, fmt, ap); + va_end(ap); + + return (r); +} diff --git a/stdio/getc.3 b/stdio/FreeBSD/getc.3 similarity index 81% rename from stdio/getc.3 rename to stdio/FreeBSD/getc.3 index 3db3eca..48c6cc0 100644 --- a/stdio/getc.3 +++ b/stdio/FreeBSD/getc.3 @@ -34,15 +34,17 @@ .\" SUCH DAMAGE. .\" .\" @(#)getc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.11 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.17 2003/02/23 01:47:47 ru Exp $ .\" -.Dd June 4, 1993 +.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 @@ -54,8 +56,12 @@ .Ft int .Fn getc "FILE *stream" .Ft int +.Fn getc_unlocked "FILE *stream" +.Ft int .Fn getchar .Ft int +.Fn getchar_unlocked "FILE *stream" +.Ft int .Fn getw "FILE *stream" .Sh DESCRIPTION The @@ -70,8 +76,7 @@ The .Fn getc function acts essentially identically to -.Fn fgetc , -but is a macro that expands in-line. +.Fn fgetc . .Pp The .Fn getchar @@ -83,14 +88,35 @@ The .Fn getw function obtains the next -.Em int +.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 . @@ -109,8 +135,10 @@ 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 @@ -122,6 +150,12 @@ and 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 @@ -132,7 +166,7 @@ and must be used to check for failure after calling .Fn getw . The size and byte order of an -.Em int +.Vt int varies from one machine to another, and .Fn getw is not recommended for portable applications. diff --git a/stdio/FreeBSD/getc.c b/stdio/FreeBSD/getc.c new file mode 100644 index 0000000..226a1fe --- /dev/null +++ b/stdio/FreeBSD/getc.c @@ -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. + */ + +#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.11 2002/08/13 09:30:41 tjr Exp $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +getc(FILE *fp) +{ + int retval; + FLOCKFILE(fp); + ORIENT(fp, -1); + retval = __sgetc(fp); + FUNLOCKFILE(fp); + return (retval); +} diff --git a/stdio/getchar.c b/stdio/FreeBSD/getchar.c similarity index 65% rename from stdio/getchar.c rename to stdio/FreeBSD/getchar.c index acba954..12bd62f 100644 --- a/stdio/getchar.c +++ b/stdio/FreeBSD/getchar.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,16 +34,30 @@ * 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.10 2002/08/13 09:30:41 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() { - return (getc(stdin)); + int retval; + FLOCKFILE(stdin); + ORIENT(stdin, -1); + retval = getc(stdin); + FUNLOCKFILE(stdin); + return (retval); } diff --git a/stdio/FreeBSD/gets.c b/stdio/FreeBSD/gets.c new file mode 100644 index 0000000..5ef23ab --- /dev/null +++ b/stdio/FreeBSD/gets.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.c b/stdio/FreeBSD/getw.c similarity index 65% rename from stdio/getw.c rename to stdio/FreeBSD/getw.c index 6a37e89..c7ba04f 100644 --- a/stdio/getw.c +++ b/stdio/FreeBSD/getw.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,6 +34,11 @@ * 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 diff --git a/stdio/FreeBSD/getwc.3 b/stdio/FreeBSD/getwc.3 new file mode 100644 index 0000000..fd6fcdb --- /dev/null +++ b/stdio/FreeBSD/getwc.3 @@ -0,0 +1,118 @@ +.\" $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.5 2002/12/04 18:57:45 ru Exp $ +.\" +.Dd October 10, 2002 +.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 +.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 . +.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 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/FreeBSD/getwc.c b/stdio/FreeBSD/getwc.c new file mode 100644 index 0000000..201b0ab --- /dev/null +++ b/stdio/FreeBSD/getwc.c @@ -0,0 +1,46 @@ +/*- + * 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.2 2002/09/28 07:43:44 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * 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(fp)); +} diff --git a/stdio/FreeBSD/getwchar.c b/stdio/FreeBSD/getwchar.c new file mode 100644 index 0000000..b0ae3ba --- /dev/null +++ b/stdio/FreeBSD/getwchar.c @@ -0,0 +1,45 @@ +/*- + * 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.2 2002/09/28 07:43:44 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Synonym for fgetwc(stdin). + */ +wint_t +getwchar(void) +{ + + return (fgetwc(stdin)); +} diff --git a/stdio/glue.h b/stdio/FreeBSD/glue.h similarity index 65% rename from stdio/glue.h rename to stdio/FreeBSD/glue.h index 42b1be3..44223ff 100644 --- a/stdio/glue.h +++ b/stdio/FreeBSD/glue.h @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -56,6 +32,9 @@ * LIABILITY, OR TORT (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 $ */ /* @@ -66,6 +45,4 @@ struct glue { struct glue *next; int niobs; FILE *iobs; -}; - -extern struct glue __sglue; +} __sglue; diff --git a/stdio/FreeBSD/glue.h.patch b/stdio/FreeBSD/glue.h.patch new file mode 100644 index 0000000..3734fe9 --- /dev/null +++ b/stdio/FreeBSD/glue.h.patch @@ -0,0 +1,9 @@ +--- glue.h.orig Fri Mar 22 15:42:01 2002 ++++ glue.h Sat May 3 14:38:31 2003 +@@ -45,4 +45,5 @@ + struct glue *next; + int niobs; + FILE *iobs; +-} __sglue; ++}; ++extern struct glue __sglue; diff --git a/stdio/FreeBSD/local.h b/stdio/FreeBSD/local.h new file mode 100644 index 0000000..5aefb45 --- /dev/null +++ b/stdio/FreeBSD/local.h @@ -0,0 +1,148 @@ +/*- + * 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.21 2002/10/25 07:01:56 tjr Exp $ + */ + +#include /* for off_t */ +#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 *); +extern wint_t __fputwc(wchar_t, FILE *); +extern int __sflush(FILE *); +extern FILE *__sfp(void); +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(FILE *, const char *, __va_list); +extern int __swsetup(FILE *); +extern int __sflags(const char *, int *); +extern int __ungetc(int, FILE *); +extern wint_t __ungetwc(wint_t, FILE *); +extern int __vfprintf(FILE *, const char *, __va_list); +extern int __vfscanf(FILE *, const char *, __va_list); +extern int __vfwprintf(FILE *, const wchar_t *, __va_list); +extern int __vfwscanf(FILE * __restrict, const wchar_t * __restrict, + __va_list); + +extern 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() */ +#ifdef notdef + /* + * XXX These are not used yet -- they will be used to store the + * multibyte conversion state for writing and reading when + * stateful encodings are supported by the locale framework. + */ + mbstate_t wstate; /* write conversion state */ + mbstate_t rstate; /* read conversion state */ +#endif +}; + +/* + * Return true iff the given FILE cannot be written now. + */ +#define cantwrite(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_INITIALIZER; \ + (fp)->_extra->fl_owner = NULL; \ + (fp)->_extra->fl_count = 0; \ + (fp)->_extra->orientation = 0; \ + /* memset(&(fp)->_extra->wstate, 0, sizeof(mbstate_t)); */ \ + /* memset(&(fp)->_extra->rstate, 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/FreeBSD/local.h.patch b/stdio/FreeBSD/local.h.patch new file mode 100644 index 0000000..b8e3b03 --- /dev/null +++ b/stdio/FreeBSD/local.h.patch @@ -0,0 +1,11 @@ +--- local.h.orig Fri Oct 25 00:01:56 2002 ++++ local.h Sat May 3 14:38:49 2003 +@@ -130,7 +130,7 @@ + + #define INITEXTRA(fp) { \ + (fp)->_extra->_up = NULL; \ +- (fp)->_extra->fl_mutex = PTHREAD_MUTEX_INITIALIZER; \ ++ (fp)->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; \ + (fp)->_extra->fl_owner = NULL; \ + (fp)->_extra->fl_count = 0; \ + (fp)->_extra->orientation = 0; \ diff --git a/stdio/makebuf.c b/stdio/FreeBSD/makebuf.c similarity index 73% rename from stdio/makebuf.c rename to stdio/FreeBSD/makebuf.c index c846fa3..a4c5c36 100644 --- a/stdio/makebuf.c +++ b/stdio/FreeBSD/makebuf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,27 +34,34 @@ * 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" /* * 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. + * optimisation) right after the _fstat() that finds the buffer size. */ void __smakebuf(fp) - register FILE *fp; + FILE *fp; { - register void *p; - register int flags; + void *p; + int flags; size_t size; int couldbetty; @@ -108,13 +91,13 @@ __smakebuf(fp) */ int __swhatbuf(fp, bufsize, couldbetty) - register FILE *fp; + FILE *fp; size_t *bufsize; int *couldbetty; { struct stat st; - if (fp->_file < 0 || fstat(fp->_file, &st) < 0) { + if (fp->_file < 0 || _fstat(fp->_file, &st) < 0) { *couldbetty = 0; *bufsize = BUFSIZ; return (__SNPT); diff --git a/stdio/mktemp.3 b/stdio/FreeBSD/mktemp.3 similarity index 98% rename from stdio/mktemp.3 rename to stdio/FreeBSD/mktemp.3 index b19d61f..0d321d7 100644 --- a/stdio/mktemp.3 +++ b/stdio/FreeBSD/mktemp.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)mktemp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.17 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.19 2002/12/24 13:41:45 ru Exp $ .\" .Dd February 11, 1998 .Dt MKTEMP 3 @@ -94,13 +94,15 @@ function acts the same as 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 -.Xr mktemp 3 +.Fn mktemp and creates the template directory, mode 0700. .Sh RETURN VALUES The diff --git a/stdio/mktemp.c b/stdio/FreeBSD/mktemp.c similarity index 80% rename from stdio/mktemp.c rename to stdio/FreeBSD/mktemp.c index c044a67..8207c17 100644 --- a/stdio/mktemp.c +++ b/stdio/FreeBSD/mktemp.c @@ -32,13 +32,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -#if 0 static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.19.2.1 2001/01/20 09:35:24 kris Exp $"; #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 @@ -48,11 +47,11 @@ static const char rcsid[] = #include #include #include -#include +#include "un-namespace.h" -char *_mktemp __P((char *)); +char *_mktemp(char *); -static int _gettemp __P((char *, int *, int, int)); +static int _gettemp(char *, int *, int, int); static const unsigned char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -80,42 +79,45 @@ char * mkdtemp(path) char *path; { - return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); + 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); + 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)); + return (_mktemp(path)); } static int _gettemp(path, doopen, domkdir, slen) char *path; - register int *doopen; + int *doopen; int domkdir; int slen; { - register char *start, *trv, *suffp; + char *start, *trv, *suffp; char *pad; struct stat sbuf; int rval; uint32_t rand; - if (doopen && domkdir) { + if (doopen != NULL && domkdir) { errno = EINVAL; - return(0); + return (0); } - for (trv = path; *trv; ++trv) + for (trv = path; *trv != '\0'; ++trv) ; trv -= slen; suffp = trv; @@ -135,19 +137,17 @@ _gettemp(path, doopen, domkdir, slen) /* * check the target directory. */ - if (doopen || domkdir) { - for (;; --trv) { - if (trv <= path) - break; + if (doopen != NULL || domkdir) { + for (; trv > path; --trv) { if (*trv == '/') { *trv = '\0'; rval = stat(path, &sbuf); *trv = '/'; if (rval != 0) - return(0); + return (0); if (!S_ISDIR(sbuf.st_mode)) { errno = ENOTDIR; - return(0); + return (0); } break; } @@ -157,24 +157,24 @@ _gettemp(path, doopen, domkdir, slen) for (;;) { if (doopen) { if ((*doopen = - open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) - return(1); + _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return (1); if (errno != EEXIST) - return(0); + return (0); } else if (domkdir) { if (mkdir(path, 0700) == 0) - return(1); + return (1); if (errno != EEXIST) - return(0); + return (0); } else if (lstat(path, &sbuf)) - return(errno == ENOENT ? 1 : 0); + return (errno == ENOENT); /* If we have a collision, cycle through the space of filenames */ for (trv = start;;) { if (*trv == '\0' || trv == suffp) - return(0); + return (0); pad = strchr(padchar, *trv); - if (pad == NULL || !*++pad) + if (pad == NULL || *++pad == '\0') *trv++ = padchar[0]; else { *trv++ = *pad; diff --git a/stdio/perror.c b/stdio/FreeBSD/perror.c similarity index 65% rename from stdio/perror.c rename to stdio/FreeBSD/perror.c index c48f0b0..658b880 100644 --- a/stdio/perror.c +++ b/stdio/FreeBSD/perror.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,23 +31,34 @@ * 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; { - register struct iovec *v; + char msgbuf[NL_TEXTMAX]; + struct iovec *v; struct iovec iov[4]; v = iov; - if (s && *s) { + if (s != NULL && *s != '\0') { v->iov_base = (char *)s; v->iov_len = strlen(s); v++; @@ -79,10 +66,15 @@ perror(s) v->iov_len = 2; v++; } - v->iov_base = strerror(errno); + 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; - (void)writev(STDERR_FILENO, iov, (v - iov) + 1); + FLOCKFILE(stderr); + __sflush(stderr); + (void)_writev(stderr->_file, iov, (v - iov) + 1); + stderr->_flags &= ~__SOFF; + FUNLOCKFILE(stderr); } diff --git a/stdio/FreeBSD/printf.3 b/stdio/FreeBSD/printf.3 new file mode 100644 index 0000000..e10be25 --- /dev/null +++ b/stdio/FreeBSD/printf.3 @@ -0,0 +1,880 @@ +.\" 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.55 2003/01/06 06:19:19 tjr Exp $ +.\" +.Dd January 4, 2003 +.Dt PRINTF 3 +.Os +.Sh NAME +.Nm printf , fprintf , sprintf , snprintf , asprintf , +.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf +.Nd formatted output conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft int +.Fn printf "const char * restrict format" ... +.Ft int +.Fn fprintf "FILE * restrict stream" "const char * restrict format" ... +.Ft int +.Fn sprintf "char * restrict str" "const char * restrict format" ... +.Ft int +.Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ... +.Ft int +.Fn asprintf "char **ret" "const char *format" ... +.In stdarg.h +.Ft int +.Fn vprintf "const char * restrict format" "va_list ap" +.Ft int +.Fn vfprintf "FILE * restrict stream" "const char * restrict format" "va_list ap" +.Ft int +.Fn vsprintf "char * restrict str" "const char * restrict format" "va_list ap" +.Ft int +.Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap" +.Ft int +.Fn vasprintf "char **ret" "const char *format" "va_list ap" +.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 str ; +and +.Fn asprintf +and +.Fn vasprintf +dynamically allocate a new string with +.Xr malloc 3 . +.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 size +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 size Ns \-1 +of the characters printed into the output string +(the +.Fa size Ns 'th +character then gets the terminating +.Ql \e0 ) ; +if the return value is greater than or equal to the +.Fa size +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 size . +.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 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" , +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 scanf 3 , +.Xr setlocale 3 , +.Xr wprintf 3 +.Rs +.%T "The FreeBSD Security Architecture" +.Re +(See +.Pa "/usr/share/doc/{to be determined}" . ) +.Sh STANDARDS +Subject to the caveats noted in the +.Sx BUGS +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 currently lack the ability to use the +.Cm ' +flag in conjunction with the +.Cm f +conversion specifier. +The +.Cm a +and +.Cm A +conversion specifiers have not yet been implemented. +The +.Cm L +modifier for floating point formats simply round the +.Vt "long double" +argument to +.Vt double , +providing no additional precision. +.Pp +The +.Nm +family of functions do not correctly handle multibyte characters in the +.Fa format +argument. diff --git a/stdio/FreeBSD/printf.3.patch b/stdio/FreeBSD/printf.3.patch new file mode 100644 index 0000000..be68e2a --- /dev/null +++ b/stdio/FreeBSD/printf.3.patch @@ -0,0 +1,52 @@ +--- printf.3.orig Thu Aug 21 18:19:02 2003 ++++ printf.3 Thu Aug 21 18:17:44 2003 +@@ -287,6 +287,20 @@ + .Xr localeconv 3 . + .El + .It ++An optional seperator character ( ++.Cm \ , | \; | \ : | _ ++) used for seperating 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 +@@ -377,6 +391,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 diff --git a/stdio/FreeBSD/printf.c b/stdio/FreeBSD/printf.c new file mode 100644 index 0000000..86452e2 --- /dev/null +++ b/stdio/FreeBSD/printf.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[] = "@(#)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 +#include + +int +printf(char const * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(stdout, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/stdio/putc.3 b/stdio/FreeBSD/putc.3 similarity index 79% rename from stdio/putc.3 rename to stdio/FreeBSD/putc.3 index 551135f..0e80b97 100644 --- a/stdio/putc.3 +++ b/stdio/FreeBSD/putc.3 @@ -34,15 +34,17 @@ .\" SUCH DAMAGE. .\" .\" @(#)putc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.8 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.14 2003/02/23 01:47:47 ru Exp $ .\" -.Dd June 4, 1993 +.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 @@ -54,8 +56,12 @@ .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" .Sh DESCRIPTION The @@ -69,36 +75,49 @@ to the output stream pointed to by .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. +function acts essentially identically to +.Fn fputc . .Pp The .Fn putchar -macro +function is identical to .Fn putc with an output stream of -.Em stdout . +.Dv stdout . .Pp The .Fn putw function writes the specified -.Em int +.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 putc , +.Fn putchar , +.Fn putc_unlocked and -.Fn putchar +.Fn putchar_unlocked return the character written. If an error occurs, the value .Dv EOF @@ -113,8 +132,10 @@ 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 @@ -124,13 +145,19 @@ 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 -.Em int +.Vt int varies from one machine to another, and .Fn putw is not recommended for portable applications. diff --git a/stdio/fgetc.c b/stdio/FreeBSD/putc.c similarity index 66% rename from stdio/fgetc.c rename to stdio/FreeBSD/putc.c index 0c97761..78f8ea7 100644 --- a/stdio/fgetc.c +++ b/stdio/FreeBSD/putc.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,12 +34,35 @@ * 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.11 2002/08/13 09:30:41 tjr Exp $"); +#include "namespace.h" #include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" +/* + * putc has traditionally been a macro in . That is no + * longer true because POSIX requires it to be thread-safe. POSIX + * does define putc_unlocked() which is defined as a macro and is + * probably what you want to use instead. + * + * #undef putc + */ int -fgetc(fp) +putc(c, fp) + int c; FILE *fp; { - return (__sgetc(fp)); + int retval; + FLOCKFILE(fp); + ORIENT(fp, -1); + retval = __sputc(c, fp); + FUNLOCKFILE(fp); + return (retval); } diff --git a/stdio/putchar.c b/stdio/FreeBSD/putchar.c similarity index 64% rename from stdio/putchar.c rename to stdio/FreeBSD/putchar.c index 3fd2aaf..5dc0170 100644 --- a/stdio/putchar.c +++ b/stdio/FreeBSD/putchar.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,11 +34,26 @@ * 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.11 2002/08/13 09:30:41 tjr Exp $"); +#include "namespace.h" #include +#include "un-namespace.h" +#include "local.h" +#include "libc_private.h" -#undef putchar - +/* + * putchar has traditionally been a macro in . That is no + * longer true because POSIX requires it to be thread-safe. POSIX + * does define putchar_unlocked() which is defined as a macro and is + * probably what you want to use instead. + * + * #undef putchar + */ /* * A subroutine version of the macro putchar */ @@ -70,7 +61,12 @@ int putchar(c) int c; { - register FILE *so = stdout; + int retval; + FILE *so = stdout; - return (__sputc(c, so)); + FLOCKFILE(so); + ORIENT(so, -1); + retval = __sputc(c, so); + FUNLOCKFILE(so); + return (retval); } diff --git a/stdio/puts.c b/stdio/FreeBSD/puts.c similarity index 67% rename from stdio/puts.c rename to stdio/FreeBSD/puts.c index 665d1bc..22697d8 100644 --- a/stdio/puts.c +++ b/stdio/FreeBSD/puts.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,10 +34,18 @@ * 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.9 2002/03/22 21:53:04 obrien Exp $"); +#include "namespace.h" #include #include +#include "un-namespace.h" #include "fvwrite.h" +#include "libc_private.h" /* * Write the given string to stdout, appending a newline. @@ -70,6 +54,7 @@ int puts(s) char const *s; { + int retval; size_t c = strlen(s); struct __suio uio; struct __siov iov[2]; @@ -81,5 +66,8 @@ puts(s) uio.uio_resid = c + 1; uio.uio_iov = &iov[0]; uio.uio_iovcnt = 2; - return (__sfvwrite(stdout, &uio) ? EOF : '\n'); + FLOCKFILE(stdout); + retval = __sfvwrite(stdout, &uio) ? EOF : '\n'; + FUNLOCKFILE(stdout); + return (retval); } diff --git a/stdio/FreeBSD/puts.c.patch b/stdio/FreeBSD/puts.c.patch new file mode 100644 index 0000000..449ecec --- /dev/null +++ b/stdio/FreeBSD/puts.c.patch @@ -0,0 +1,30 @@ +--- puts.c.orig Tue May 20 15:22:43 2003 ++++ puts.c Thu Jul 31 13:21:00 2003 +@@ -47,6 +47,9 @@ + #include "fvwrite.h" + #include "libc_private.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. + */ +@@ -55,12 +58,15 @@ + char const *s; + { + int retval; +- size_t c = strlen(s); ++ 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; ++ iov[0].iov_len = c = strlen(s); + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + uio.uio_resid = c + 1; diff --git a/stdio/putw.c b/stdio/FreeBSD/putw.c similarity index 66% rename from stdio/putw.c rename to stdio/FreeBSD/putw.c index b8ef6d9..ee0c23b 100644 --- a/stdio/putw.c +++ b/stdio/FreeBSD/putw.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,15 +34,24 @@ * 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; @@ -74,5 +59,8 @@ putw(w, fp) iov.iov_len = uio.uio_resid = sizeof(w); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - return (__sfvwrite(fp, &uio)); + FLOCKFILE(fp); + retval = __sfvwrite(fp, &uio); + FUNLOCKFILE(fp); + return (retval); } diff --git a/gen/frexp.3 b/stdio/FreeBSD/putwc.3 similarity index 63% rename from gen/frexp.3 rename to stdio/FreeBSD/putwc.3 index 74836cc..b117a04 100644 --- a/gen/frexp.3 +++ b/stdio/FreeBSD/putwc.3 @@ -1,9 +1,11 @@ -.\" Copyright (c) 1991, 1993 +.\" $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 -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. +.\" 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 @@ -33,56 +35,73 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)frexp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/frexp.3,v 1.9 2001/10/01 16:08:50 ru Exp $ +.\" @(#)putc.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: src/lib/libc/stdio/putwc.3,v 1.6 2002/12/04 18:57:45 ru Exp $ .\" -.Dd June 4, 1993 -.Dt FREXP 3 +.Dd October 10, 2002 +.Dt PUTWC 3 .Os .Sh NAME -.Nm frexp -.Nd convert floating-point number to fractional and integral components +.Nm fputwc , +.Nm putwc , +.Nm putwchar +.Nd output a wide-character to a stream .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In math.h -.Ft double -.Fn frexp "double value" "int *exp" +.In stdio.h +.In wchar.h +.Ft wint_t +.Fn fputwc "wchar_t wc" "FILE *stream" +.Ft wint_t +.Fn putwc "wchar_t wc" "FILE *stream" +.Ft wint_t +.Fn putwchar "wchar_t wc" .Sh DESCRIPTION The -.Fn frexp -function breaks a floating-point number into a normalized -fraction and an integral power of 2. -It stores the integer in the -.Em int -object pointed to by -.Fa exp . +.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 . .Sh RETURN VALUES The -.Fn frexp -function returns the value -.Em x , -such that -.Em x -is a -.Em double -with magnitude in the interval -.Bo 1/2 , 1 Pc -or zero, and -.Fa value -equals -.Em x -times 2 raised to the power -.Fa *exp . -If -.Fa value -is zero, both parts of the result are zero. +.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 ldexp 3 , -.Xr math 3 , -.Xr modf 3 +.Xr ferror 3 , +.Xr fopen 3 , +.Xr getwc 3 , +.Xr putc 3 , +.Xr stdio 3 .Sh STANDARDS The -.Fn frexp -function conforms to -.St -isoC . +.Fn fputwc , +.Fn putwc , +and +.Fn putwchar +functions +conform to +.St -isoC-99 . diff --git a/stdio/FreeBSD/putwc.c b/stdio/FreeBSD/putwc.c new file mode 100644 index 0000000..a33f78f --- /dev/null +++ b/stdio/FreeBSD/putwc.c @@ -0,0 +1,46 @@ +/*- + * 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.2 2002/09/28 07:43:44 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * 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(wc, fp)); +} diff --git a/stdio/FreeBSD/putwchar.c b/stdio/FreeBSD/putwchar.c new file mode 100644 index 0000000..a39e070 --- /dev/null +++ b/stdio/FreeBSD/putwchar.c @@ -0,0 +1,45 @@ +/*- + * 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.2 2002/09/28 07:43:44 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Synonym for fputwc(wc, stdout). + */ +wint_t +putwchar(wchar_t wc) +{ + + return (fputwc(wc, stdout)); +} diff --git a/stdio/refill.c b/stdio/FreeBSD/refill.c similarity index 72% rename from stdio/refill.c rename to stdio/FreeBSD/refill.c index 485f511..edd8bb6 100644 --- a/stdio/refill.c +++ b/stdio/FreeBSD/refill.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,20 +34,34 @@ * 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(fp) - FILE *fp; +lflush(FILE *fp) { + int ret = 0; - if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) - return (__sflush(fp)); - return (0); + if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) { + FLOCKFILE(fp); + ret = __sflush(fp); + FUNLOCKFILE(fp); + } + return (ret); } /* @@ -79,14 +69,15 @@ lflush(fp) * Return EOF on eof or error, 0 otherwise. */ int -__srefill(fp) - register FILE *fp; +__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 */ @@ -97,6 +88,7 @@ __srefill(fp) if ((fp->_flags & __SRD) == 0) { if ((fp->_flags & __SRW) == 0) { errno = EBADF; + fp->_flags |= __SERR; return (EOF); } /* switch to reading */ @@ -118,7 +110,7 @@ __srefill(fp) if (HASUB(fp)) { FREEUB(fp); if ((fp->_r = fp->_ur) != 0) { - fp->_p = fp->_up; + fp->_p = fp->_extra->_up; return (0); } } @@ -132,10 +124,18 @@ __srefill(fp) * flush all line buffered output files, per the ANSI C * standard. */ - if (fp->_flags & (__SLBF|__SNBF)) + 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 = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); + 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) diff --git a/stdio/remove.3 b/stdio/FreeBSD/remove.3 similarity index 100% rename from stdio/remove.3 rename to stdio/FreeBSD/remove.3 diff --git a/stdio/remove.c b/stdio/FreeBSD/remove.c similarity index 94% rename from stdio/remove.c rename to stdio/FreeBSD/remove.c index 4e20f08..2553f64 100644 --- a/stdio/remove.c +++ b/stdio/FreeBSD/remove.c @@ -35,12 +35,10 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -#if 0 static char sccsid[] = "@(#)remove.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdio/remove.c,v 1.6.2.1 2000/09/20 04:43:12 jkh Exp $"; #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 diff --git a/stdio/FreeBSD/rewind.c b/stdio/FreeBSD/rewind.c new file mode 100644 index 0000000..76f2ed3 --- /dev/null +++ b/stdio/FreeBSD/rewind.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) { + clearerr_unlocked(fp); + errno = serrno; + } + FUNLOCKFILE(fp); +} diff --git a/stdio/rget.c b/stdio/FreeBSD/rget.c similarity index 66% rename from stdio/rget.c rename to stdio/FreeBSD/rget.c index 15a5edb..9b7f586 100644 --- a/stdio/rget.c +++ b/stdio/FreeBSD/rget.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,8 +34,14 @@ * 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: @@ -67,8 +49,7 @@ * in the newly-filled buffer. */ int -__srget(fp) - register FILE *fp; +__srget(FILE *fp) { if (__srefill(fp) == 0) { fp->_r--; diff --git a/stdio/scanf.3 b/stdio/FreeBSD/scanf.3 similarity index 69% rename from stdio/scanf.3 rename to stdio/FreeBSD/scanf.3 index 776ab49..3f5913a 100644 --- a/stdio/scanf.3 +++ b/stdio/FreeBSD/scanf.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)scanf.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/stdio/scanf.3,v 1.13 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/scanf.3,v 1.24 2003/06/28 09:03:25 das Exp $ .\" -.Dd December 11, 1993 +.Dd January 4, 2003 .Dt SCANF 3 .Os .Sh NAME @@ -52,18 +52,18 @@ .Sh SYNOPSIS .In stdio.h .Ft int -.Fn scanf "const char *format" ... +.Fn scanf "const char * restrict format" ... .Ft int -.Fn fscanf "FILE *stream" "const char *format" ... +.Fn fscanf "FILE * restrict stream" "const char * restrict format" ... .Ft int -.Fn sscanf "const char *str" "const char *format" ... +.Fn sscanf "const char * restrict str" "const char * restrict format" ... .In stdarg.h .Ft int -.Fn vscanf "const char *format" "va_list ap" +.Fn vscanf "const char * restrict format" "va_list ap" .Ft int -.Fn vsscanf "const char *str" "const char *format" "va_list ap" +.Fn vsscanf "const char * restrict str" "const char * restrict format" "va_list ap" .Ft int -.Fn vfscanf "FILE *stream" "const char *format" "va_list ap" +.Fn vfscanf "FILE * restrict stream" "const char * restrict format" "va_list ap" .Sh DESCRIPTION The .Fn scanf @@ -80,7 +80,7 @@ The .Fn scanf function reads input from the standard input stream -.Em stdin , +.Dv stdin , .Fn fscanf reads input from the stream pointer .Fa stream , @@ -113,7 +113,9 @@ Each successive .Em pointer argument must correspond properly with each successive conversion specifier -(but see `suppression' below). +(but see the +.Cm * +conversion below). All conversions are introduced by the .Cm % (percent sign) character. @@ -137,52 +139,108 @@ character introducing a conversion there may be a number of .Em flag characters, as follows: -.Bl -tag -width indent +.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 -.Em short int +.Vt "short int" (rather than -.Em int ) . -.It Cm l -Indicates either that the conversion will be one of +.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 -.Em long int +.Vt "long int" (rather than -.Em int ) , -or that the conversion will be one of -.Cm efg +.Vt int ) , +that the conversion will be one of +.Cm a , e , f , +or +.Cm g and the next pointer is a pointer to -.Em double +.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 -.Em float ) . +.Vt int ) . .It Cm L -Indicates that the conversion will be -.Cm efg +Indicates that the conversion will be one of +.Cm a , e , f , +or +.Cm g and the next pointer is a pointer to -.Em long double . -(This type is not implemented; the -.Cm L -flag is currently ignored.) +.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 -Indicates either that the conversion will be one of +(deprecated.) +Indicates that the conversion will be one of .Cm dioux or .Cm n and the next pointer is a pointer to a -.Em long long int +.Vt "long long int" (rather than -.Em int ) , +.Vt int ) . .El .Pp In addition to these flags, @@ -192,9 +250,18 @@ between the .Cm % and the conversion. If no width is given, -a default of `infinity' is used (with one exception, below); -otherwise at most this many characters are scanned +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. @@ -202,22 +269,23 @@ this white space is not counted against the field width. The following conversions are available: .Bl -tag -width XXXX .It Cm % -Matches a literal `%'. -That is, `%\&%' in the format string -matches a single input `%' character. +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 -.Em int . -.It Cm D -Equivalent to -.Cm ld ; -this exists only for backwards compatibility. +.Vt int . .It Cm i Matches an optionally signed integer; the next pointer must be a pointer to -.Em int . +.Vt int . The integer is read in base 16 if it begins with .Ql 0x @@ -230,77 +298,73 @@ Only characters that correspond to the base are used. .It Cm o Matches an octal integer; the next pointer must be a pointer to -.Em unsigned int . -.It Cm O -Equivalent to -.Cm lo ; -this exists for backwards compatibility. +.Vt "unsigned int" . .It Cm u Matches an optionally signed decimal integer; the next pointer must be a pointer to -.Em unsigned int . -.It Cm x +.Vt "unsigned int" . +.It Cm x , X Matches an optionally signed hexadecimal integer; the next pointer must be a pointer to -.Em unsigned int . -.It Cm X -Equivalent to -.Cm lx ; -this violates the -.St -isoC , -but is backwards compatible with previous -.Ux -systems. -.It Cm f -Matches an optionally signed floating-point number; -the next pointer must be a pointer to -.Em float . -.It Cm e -Equivalent to -.Cm f . -.It Cm g -Equivalent to -.Cm f . -.It Cm E -Equivalent to -.Cm lf ; -this violates the -.St -isoC , -but is backwards compatible with previous -.Ux -systems. -.It Cm F -Equivalent to -.Cm lf ; -this exists only for backwards compatibility. +.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 -.Em char , +.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 -.Em char , +.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 -.Em char , +.Vt char , and there must be enough room for all the characters in the string, plus a terminating .Dv NUL @@ -333,24 +397,31 @@ To include a hyphen, make it the last character before the final close bracket. For instance, .Ql [^]0-9-] -means the set `everything except close bracket, zero through nine, -and hyphen'. +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 -.Em void . +.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 -.Em int . +.Vt int . This is .Em not a conversion, although it can be suppressed with the @@ -362,30 +433,12 @@ The decimal point character is defined in the program's locale (category .Dv LC_NUMERIC ) . .Pp -For backwards compatibility, -other conversion characters (except -.Ql \e0 ) -are taken as if they were -.Ql %d -or, if uppercase, -.Ql %ld , -and a `conversion' of +For backwards compatibility, a +.Dq conversion +of .Ql %\e0 causes an immediate return of .Dv EOF . -The -.Cm F -and -.Cm X -conversions will be changed in the future -to conform to the -.Tn ANSI -C standard, -after which they will act like -.Cm f -and -.Cm x -respectively. .Sh RETURN VALUES These functions @@ -408,33 +461,41 @@ 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 strtod 3 , .Xr strtol 3 , -.Xr strtoul 3 +.Xr strtoul 3 , +.Xr wscanf 3 .Sh STANDARDS The functions .Fn fscanf , .Fn scanf , +.Fn sscanf , +.Fn vfscanf , +.Fn vscanf and -.Fn sscanf -conform to -.St -isoC . -.Sh HISTORY -The functions -.Fn vscanf , .Fn vsscanf -and -.Fn vfscanf -are new to this release. +conform to +.St -isoC-99 . .Sh BUGS -The current situation with -.Cm %F +Earlier implementations of +.Nm +treated +.Cm \&%D , \&%E , \&%F , \&%O and -.Cm %X -conversions is unfortunate. -.Pp -All of the backwards compatibility formats will be removed in the future. +.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 @@ -444,3 +505,13 @@ 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/FreeBSD/scanf.c b/stdio/FreeBSD/scanf.c new file mode 100644 index 0000000..b4fb1a3 --- /dev/null +++ b/stdio/FreeBSD/scanf.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[] = "@(#)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 "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(stdin, fmt, ap); + FUNLOCKFILE(stdin); + va_end(ap); + return (ret); +} diff --git a/stdio/setbuf.3 b/stdio/FreeBSD/setbuf.3 similarity index 93% rename from stdio/setbuf.3 rename to stdio/FreeBSD/setbuf.3 index bf88ada..37055a7 100644 --- a/stdio/setbuf.3 +++ b/stdio/FreeBSD/setbuf.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.10 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.14 2002/12/19 09:40:24 ru Exp $ .\" .Dd June 4, 1993 .Dt SETBUF 3 @@ -50,13 +50,13 @@ .Sh SYNOPSIS .In stdio.h .Ft void -.Fn setbuf "FILE *stream" "char *buf" +.Fn setbuf "FILE * restrict stream" "char * restrict buf" .Ft void .Fn setbuffer "FILE *stream" "char *buf" "int size" .Ft int .Fn setlinebuf "FILE *stream" .Ft int -.Fn setvbuf "FILE *stream" "char *buf" "int mode" "size_t size" +.Fn setvbuf "FILE * restrict stream" "char * restrict buf" "int mode" "size_t size" .Sh DESCRIPTION The three types of buffering available are unbuffered, block buffered, and line buffered. @@ -65,7 +65,8 @@ 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 stdin). +(typically +.Dv stdin ) . The function .Xr fflush 3 may be used to force the block out early. @@ -81,10 +82,10 @@ is called, and an optimally-sized buffer is obtained. If a stream refers to a terminal (as -.Em stdout +.Dv stdout normally does) it is line buffered. The standard error stream -.Em stderr +.Dv stderr is always unbuffered. .Pp The @@ -93,7 +94,7 @@ function may be used to alter the buffering behavior of a stream. The .Fa mode -parameter must be one of the following three macros: +argument must be one of the following three macros: .Bl -tag -width _IOFBF -offset indent .It Dv _IONBF unbuffered @@ -105,7 +106,7 @@ fully buffered .Pp The .Fa size -parameter may be given as zero +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 diff --git a/stdio/setbuf.c b/stdio/FreeBSD/setbuf.c similarity index 64% rename from stdio/setbuf.c rename to stdio/FreeBSD/setbuf.c index d08bb59..5eb6fb1 100644 --- a/stdio/setbuf.c +++ b/stdio/FreeBSD/setbuf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,14 +34,17 @@ * 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(fp, buf) - FILE *fp; - char *buf; +setbuf(FILE * __restrict fp, char * __restrict buf) { (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ); } diff --git a/stdio/setbuffer.c b/stdio/FreeBSD/setbuffer.c similarity index 65% rename from stdio/setbuffer.c rename to stdio/FreeBSD/setbuffer.c index 7a3f16e..6ec4376 100644 --- a/stdio/setbuffer.c +++ b/stdio/FreeBSD/setbuffer.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,17 +34,22 @@ * 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) - register FILE *fp; + FILE *fp; char *buf; int size; { - (void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size); + (void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size); } /* diff --git a/stdio/setvbuf.c b/stdio/FreeBSD/setvbuf.c similarity index 78% rename from stdio/setvbuf.c rename to stdio/FreeBSD/setvbuf.c index e9934a4..166d5b1 100644 --- a/stdio/setvbuf.c +++ b/stdio/FreeBSD/setvbuf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,23 +34,27 @@ * 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(fp, buf, mode, size) - register FILE *fp; - char *buf; - register int mode; - register size_t size; +setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size) { - register int ret, flags; + int ret, flags; size_t iosize; int ttyflag; @@ -87,6 +67,7 @@ setvbuf(fp, buf, mode, size) 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 @@ -101,7 +82,7 @@ setvbuf(fp, buf, mode, size) flags = fp->_flags; if (flags & __SMBF) free((void *)fp->_bf._base); - flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF); + flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SOFF | __SNPT | __SEOF); /* If setting unbuffered mode, skip all the hard work. */ if (mode == _IONBF) @@ -138,6 +119,7 @@ nbf: fp->_w = 0; fp->_bf._base = fp->_p = fp->_nbuf; fp->_bf._size = 1; + FUNLOCKFILE(fp); return (ret); } flags |= __SMBF; @@ -178,5 +160,6 @@ nbf: } __cleanup = _cleanup; + FUNLOCKFILE(fp); return (ret); } diff --git a/stdio/FreeBSD/snprintf.c b/stdio/FreeBSD/snprintf.c new file mode 100644 index 0000000..b381852 --- /dev/null +++ b/stdio/FreeBSD/snprintf.c @@ -0,0 +1,75 @@ +/*- + * 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 +#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, fmt, ap); + if (on > 0) + *f._p = '\0'; + va_end(ap); + return (ret); +} diff --git a/stdio/FreeBSD/sprintf.c b/stdio/FreeBSD/sprintf.c new file mode 100644 index 0000000..6b9ed99 --- /dev/null +++ b/stdio/FreeBSD/sprintf.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[] = "@(#)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 +#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, fmt, ap); + va_end(ap); + *f._p = 0; + return (ret); +} diff --git a/stdio/sscanf.c b/stdio/FreeBSD/sscanf.c similarity index 65% rename from stdio/sscanf.c rename to stdio/FreeBSD/sscanf.c index 067b7f6..b4850cd 100644 --- a/stdio/sscanf.c +++ b/stdio/FreeBSD/sscanf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,16 +34,19 @@ * 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 #include -#if __STDC__ #include -#else -#include -#endif #include "local.h" +static int eofread(void *, char *, int); + /* ARGSUSED */ static int eofread(cookie, buf, len) @@ -80,30 +59,23 @@ eofread(cookie, buf, len) } int -#if __STDC__ -sscanf(const char *str, char const *fmt, ...) -#else -sscanf(str, fmt, va_alist) - char *str; - char *fmt; - va_dcl -#endif +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; -#if __STDC__ + f._extra = &extra; + INITEXTRA(&f); va_start(ap, fmt); -#else - va_start(ap); -#endif ret = __svfscanf(&f, fmt, ap); va_end(ap); return (ret); diff --git a/stdio/FreeBSD/sscanf.c.patch b/stdio/FreeBSD/sscanf.c.patch new file mode 100644 index 0000000..4d09cc9 --- /dev/null +++ b/stdio/FreeBSD/sscanf.c.patch @@ -0,0 +1,20 @@ +Index: sscanf.c +=================================================================== +RCS file: /cvs/root/Libc/stdio/FreeBSD/sscanf.c,v +retrieving revision 1.2 +diff -u -d -b -w -u -r1.2 sscanf.c +--- sscanf.c 2003/05/20 22:22:44 1.2 ++++ sscanf.c 2003/06/03 06:56:38 +@@ -66,6 +66,12 @@ + struct __sFILEX extra; + FILE f; + ++#if defined(__APPLE_PR3275149_HACK__) ++ /* If the string is NULL and we're using the broken Jaguar behavior, there's no sense in proceeding any further since we know we can return 0 */ ++ if (str && str[0] == '\0') ++ return 0; ++#endif ++ + f._file = -1; + f._flags = __SRD; + f._bf._base = f._p = (unsigned char *)str; diff --git a/stdio/stdio.3 b/stdio/FreeBSD/stdio.3 similarity index 86% rename from stdio/stdio.3 rename to stdio/FreeBSD/stdio.3 index 59fd492..95aba8c 100644 --- a/stdio/stdio.3 +++ b/stdio/FreeBSD/stdio.3 @@ -30,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)stdio.3 8.7 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/stdio/stdio.3,v 1.18 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/stdio.3,v 1.24 2003/02/23 01:47:47 ru Exp $ .\" -.Dd April 19, 1994 +.Dd January 10, 2003 .Dt STDIO 3 .Os .Sh NAME @@ -127,9 +127,9 @@ opened explicitly: (for writing diagnostic output). .El These streams are abbreviated -.Em stdin , stdout +.Dv stdin , stdout and -.Em stderr . +.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 @@ -172,13 +172,13 @@ looks like and which external variables are of interest. The following are defined as macros; these names may not be re-used without first removing their current definitions with -.Dv #undef : +.Ic #undef : .Dv BUFSIZ , .Dv EOF , .Dv FILENAME_MAX , .Dv FOPEN_MAX , -.Dv L_cuserid , .Dv L_ctermid , +.Dv L_cuserid , .Dv L_tmpnam , .Dv NULL , .Dv P_tmpdir , @@ -186,30 +186,30 @@ without first removing their current definitions with .Dv SEEK_END , .Dv SEEK_SET , .Dv TMP_MAX , -.Dv clearerr , -.Dv feof , -.Dv ferror , -.Dv fileno , +.Dv clearerr_unlocked , +.Dv feof_unlocked , +.Dv ferror_unlocked , +.Dv fileno_unlocked , .Dv fropen , .Dv fwopen , -.Dv getc , -.Dv getchar , -.Dv putc , -.Dv putchar , +.Dv getc_unlocked , +.Dv getchar_unlocked , +.Dv putc_unlocked , +.Dv putchar_unlocked , .Dv stderr , -.Dv stdin , -.Dv stdout , -.Dv vfscanf . +.Dv stdin +and +.Dv stdout . Function versions of the macro functions -.Fn clearerr , -.Fn feof , -.Fn ferror , -.Fn fileno , -.Fn getc , -.Fn getchar , -.Fn putc , +.Dv clearerr_unlocked , +.Dv feof_unlocked , +.Dv ferror_unlocked , +.Dv fileno_unlocked , +.Dv getc_unlocked , +.Dv getchar_unlocked , +.Dv putc_unlocked and -.Fn putchar +.Dv putchar_unlocked exist and will be used if the macro definitions are explicitly removed. .Sh SEE ALSO @@ -225,7 +225,7 @@ library and system functions, especially The .Nm library conforms to -.St -isoC . +.St -isoC-99 . .Sh LIST OF FUNCTIONS .Bl -column "Description" .It Sy "Function Description" @@ -240,12 +240,16 @@ library conforms to .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" @@ -254,13 +258,17 @@ library conforms to .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 "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 "mkdtemp create unique temporary file" +.It "getwc get next wide character from input stream" +.It "getwchar get next wide character from input stream" +.It "mkdtemp create unique temporary directory" .It "mkstemp create unique temporary file" .It "mktemp create unique temporary file" .It "perror system error messages" @@ -269,6 +277,8 @@ library conforms to .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 "remove remove directory entry" .It "rewind reposition a stream" .It "scanf input format conversion" @@ -280,18 +290,24 @@ library conforms to .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 "tempnam temporary file routines" .It "tmpfile temporary file routines" .It "tmpnam temporary file routines" .It "ungetc un-get character from input stream" +.It "ungetwc un-get wide character from input stream" .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 "wprintf formatted wide character output conversion" .El diff --git a/stdio/stdio.c b/stdio/FreeBSD/stdio.c similarity index 52% rename from stdio/stdio.c rename to stdio/FreeBSD/stdio.c index ae9d996..233427c 100644 --- a/stdio/stdio.c +++ b/stdio/FreeBSD/stdio.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,15 +34,24 @@ * 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 +#include "un-namespace.h" #include "local.h" /* * Small standard I/O/seek/close functions. - * These maintain the `known seek offset' for seek optimisation. */ int __sread(cookie, buf, n) @@ -74,16 +59,9 @@ __sread(cookie, buf, n) char *buf; int n; { - register FILE *fp = cookie; - register int ret; - - ret = read(fp->_file, buf, n); - /* if the read succeeded, update the current offset */ - if (ret >= 0) - fp->_offset += ret; - else - fp->_flags &= ~__SOFF; /* paranoia */ - return (ret); + FILE *fp = cookie; + + return(_read(fp->_file, buf, (size_t)n)); } int @@ -92,12 +70,9 @@ __swrite(cookie, buf, n) char const *buf; int n; { - register FILE *fp = cookie; + FILE *fp = cookie; - if (fp->_flags & __SAPP) - (void) lseek(fp->_file, (off_t)0, SEEK_END); - fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */ - return (write(fp->_file, buf, n)); + return (_write(fp->_file, buf, (size_t)n)); } fpos_t @@ -106,17 +81,9 @@ __sseek(cookie, offset, whence) fpos_t offset; int whence; { - register FILE *fp = cookie; - register off_t ret; - - ret = lseek(fp->_file, (off_t)offset, whence); - if (ret == -1L) - fp->_flags &= ~__SOFF; - else { - fp->_flags |= __SOFF; - fp->_offset = ret; - } - return (ret); + FILE *fp = cookie; + + return (lseek(fp->_file, (off_t)offset, whence)); } int @@ -124,5 +91,101 @@ __sclose(cookie) void *cookie; { - return (close(((FILE *)cookie)->_file)); + 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/FreeBSD/swprintf.c b/stdio/FreeBSD/swprintf.c new file mode 100644 index 0000000..190326a --- /dev/null +++ b/stdio/FreeBSD/swprintf.c @@ -0,0 +1,45 @@ +/*- + * 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 +#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(s, n, fmt, ap); + va_end(ap); + + return (ret); +} diff --git a/stdio/FreeBSD/swscanf.c b/stdio/FreeBSD/swscanf.c new file mode 100644 index 0000000..81ac9f1 --- /dev/null +++ b/stdio/FreeBSD/swscanf.c @@ -0,0 +1,45 @@ +/*- + * 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 +#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(str, fmt, ap); + va_end(ap); + + return (r); +} diff --git a/stdio/tempnam.c b/stdio/FreeBSD/tempnam.c similarity index 68% rename from stdio/tempnam.c rename to stdio/FreeBSD/tempnam.c index d236e0e..d4dbaa3 100644 --- a/stdio/tempnam.c +++ b/stdio/FreeBSD/tempnam.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,14 +31,25 @@ * 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 +__warn_references(tempnam, + "warning: tempnam() possibly used unsafely; consider using mkstemp()"); + +extern char *_mktemp(char *); + char * tempnam(dir, pfx) const char *dir, *pfx; @@ -76,28 +63,28 @@ tempnam(dir, pfx) if (!pfx) pfx = "tmp."; - if (f = getenv("TMPDIR")) { + 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); } - if (f = (char *)dir) { + if ((f = (char *)dir)) { (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, *(f + strlen(f) - 1) == '/'? "": "/", pfx); - if (f = mktemp(name)) + if ((f = _mktemp(name))) return(f); } f = P_tmpdir; (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); - if (f = mktemp(name)) + if ((f = _mktemp(name))) return(f); f = _PATH_TMP; (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); - if (f = mktemp(name)) + if ((f = _mktemp(name))) return(f); sverrno = errno; diff --git a/stdio/tmpfile.c b/stdio/FreeBSD/tmpfile.c similarity index 63% rename from stdio/tmpfile.c rename to stdio/FreeBSD/tmpfile.c index 3cae1f0..cf5b70a 100644 --- a/stdio/tmpfile.c +++ b/stdio/FreeBSD/tmpfile.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,22 @@ * 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() @@ -73,26 +58,37 @@ tmpfile() FILE *fp; int fd, sverrno; #define TRAILER "tmp.XXXXXX" - char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)]; + char *buf; + const char *tmpdir; - (void)memcpy(buf, _PATH_TMP, sizeof(_PATH_TMP) - 1); - (void)memcpy(buf + sizeof(_PATH_TMP) - 1, TRAILER, sizeof(TRAILER)); + 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); + (void)_sigprocmask(SIG_BLOCK, &set, &oset); fd = mkstemp(buf); if (fd != -1) (void)unlink(buf); - (void)sigprocmask(SIG_SETMASK, &oset, NULL); + free(buf); + + (void)_sigprocmask(SIG_SETMASK, &oset, NULL); if (fd == -1) return (NULL); if ((fp = fdopen(fd, "w+")) == NULL) { sverrno = errno; - (void)close(fd); + (void)_close(fd); errno = sverrno; return (NULL); } diff --git a/stdio/tmpnam.3 b/stdio/FreeBSD/tmpnam.3 similarity index 81% rename from stdio/tmpnam.3 rename to stdio/FreeBSD/tmpnam.3 index fa4c1e9..edf075f 100644 --- a/stdio/tmpnam.3 +++ b/stdio/FreeBSD/tmpnam.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)tmpnam.3 8.2 (Berkeley) 11/17/93 -.\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.10 2001/10/01 16:08:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdio/tmpnam.3,v 1.14 2002/12/18 12:45:10 ru Exp $ .\" .Dd November 17, 1993 .Dt TMPFILE 3 @@ -132,7 +132,9 @@ if .Pf non- Dv NULL , is used to specify a file name prefix, which will be the first part of the created file name. -.Fn Tempnam +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 . @@ -182,48 +184,61 @@ for any of the errors specified for the library functions .Xr malloc 3 or .Xr mktemp 3 . -.Sh SEE ALSO -.Xr mkstemp 3 , -.Xr mktemp 3 -.Sh STANDARDS +.Sh SECURITY CONSIDERATIONS The -.Fn tmpfile -and .Fn tmpnam -functions -conform to -.St -isoC . -.Sh BUGS -These interfaces are provided for System V and +and +.Fn tempnam +functions are susceptible to a race condition +occuring 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. -The -.Xr mkstemp 3 -interface is strongly preferred. .Pp -There are four important problems with these interfaces (as well as -with the historic -.Xr mktemp 3 -interface). -First, there is an obvious race between file name selection and file -creation and deletion. -Second, most historic implementations provide only a limited number -of possible temporary file names (usually 26) before file names will -start being recycled. -Third, the System V implementations of these functions (and of +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 -function 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. -Finally, there is no specification of the permissions with which the -temporary files are created. +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 -This implementation does not have these flaws, but portable software -cannot depend on that. -In particular, the +The .Fn tmpfile interface should not be used in software expected to be used on other systems if there is any possibility that the user does not wish the temporary file to be publicly readable and writable. +.Sh SEE ALSO +.Xr mkstemp 3 , +.Xr mktemp 3 +.Rs +.%T "The FreeBSD Security Architecture" +.Re +(See +.Pa "/usr/share/doc/{to be determined}" . ) +.Sh STANDARDS +The +.Fn tmpfile +and +.Fn tmpnam +functions +conform to +.St -isoC . diff --git a/stdio/tmpnam.c b/stdio/FreeBSD/tmpnam.c similarity index 64% rename from stdio/tmpnam.c rename to stdio/FreeBSD/tmpnam.c index 0221ee4..38fcdd6 100644 --- a/stdio/tmpnam.c +++ b/stdio/FreeBSD/tmpnam.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,29 +34,32 @@ * 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 -#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 = NULL; - - if( buf == NULL ) { - buf = malloc(L_tmpnam); - if( buf == NULL ) - return NULL; - } + 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)); + return (_mktemp(s)); } diff --git a/stdio/ungetc.3 b/stdio/FreeBSD/ungetc.3 similarity index 96% rename from stdio/ungetc.3 rename to stdio/FreeBSD/ungetc.3 index adb91fa..0c0bf83 100644 --- a/stdio/ungetc.3 +++ b/stdio/FreeBSD/ungetc.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/ungetc.3,v 1.12 2001/10/01 16:08:59 ru Exp $ +.\" $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 @@ -93,7 +93,8 @@ the operation will fail and the stream will remain unchanged. .Sh SEE ALSO .Xr fseek 3 , .Xr getc 3 , -.Xr setvbuf 3 +.Xr setvbuf 3 , +.Xr ungetwc 3 .Sh STANDARDS The .Fn ungetc diff --git a/stdio/ungetc.c b/stdio/FreeBSD/ungetc.c similarity index 77% rename from stdio/ungetc.c rename to stdio/FreeBSD/ungetc.c index a58e65b..c98ab5a 100644 --- a/stdio/ungetc.c +++ b/stdio/FreeBSD/ungetc.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,11 +34,21 @@ * 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.14 2002/08/13 09:30:41 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 @@ -71,11 +57,10 @@ * are all at the end (stack-style). */ static int -__submore(fp) - register FILE *fp; +__submore(FILE *fp) { - register int i; - register unsigned char *p; + int i; + unsigned char *p; if (fp->_ub._base == fp->_ubuf) { /* @@ -92,7 +77,7 @@ __submore(fp) return (0); } i = fp->_ub._size; - p = realloc(fp->_ub._base, i << 1); + 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 */ @@ -103,15 +88,35 @@ __submore(fp) return (0); } +/* + * MT-safe version + */ int -ungetc(c, fp) - int c; - register FILE *fp; +ungetc(int c, FILE *fp) { + int ret; + if (c == EOF) return (EOF); if (!__sdidinit) __sinit(); + FLOCKFILE(fp); + ret = __ungetc(c, fp); + FUNLOCKFILE(fp); + return (ret); +} + +/* + * Non-MT-safe version + */ +int +__ungetc(int c, FILE *fp) +{ + + ORIENT(fp, -1); + + if (c == EOF) + return (EOF); if ((fp->_flags & __SRD) == 0) { /* * Not already reading: no good unless reading-and-writing. @@ -160,7 +165,7 @@ ungetc(c, fp) * Initially, we will use the `reserve' buffer. */ fp->_ur = fp->_r; - fp->_up = fp->_p; + fp->_extra->_up = fp->_p; fp->_ub._base = fp->_ubuf; fp->_ub._size = sizeof(fp->_ubuf); fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; diff --git a/stdio/FreeBSD/ungetwc.3 b/stdio/FreeBSD/ungetwc.3 new file mode 100644 index 0000000..2a3c91b --- /dev/null +++ b/stdio/FreeBSD/ungetwc.3 @@ -0,0 +1,99 @@ +.\" $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.4 2002/12/04 17:49:15 ru Exp $ +.\" +.Dd October 24, 2001 +.Dt UNGETWC 3 +.Os +.Sh NAME +.Nm ungetwc +.Nd un-get wide-character from input stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft wint_t +.Fn ungetwc "wint_t wc" "FILE *stream" +.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 by subsequent reads on the +stream (in reverse order). +A successful intervening call, using the same stream, to one of the file +positioning functions +.Xr fseek 3 , +.Xr fsetpos 3 , +or +.Xr rewind 3 +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. +.Pp +If a character is successfully pushed-back, +the end-of-file indicator for the stream is cleared. +.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 +.Sh STANDARDS +The +.Fn ungetwc +function conforms to +.St -isoC-99 . diff --git a/stdio/FreeBSD/ungetwc.c b/stdio/FreeBSD/ungetwc.c new file mode 100644 index 0000000..62415d3 --- /dev/null +++ b/stdio/FreeBSD/ungetwc.c @@ -0,0 +1,77 @@ +/*- + * 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/ungetwc.c,v 1.5 2002/10/16 12:09:43 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Non-MT-safe version. + */ +wint_t +__ungetwc(wint_t wc, FILE *fp) +{ + char buf[MB_LEN_MAX]; + mbstate_t mbs; + size_t len; + + if (wc == WEOF) + return (WEOF); + memset(&mbs, 0, sizeof(mbs)); + if ((len = wcrtomb(buf, wc, &mbs)) == (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); + FUNLOCKFILE(fp); + + return (r); +} diff --git a/stdio/FreeBSD/unlocked.c b/stdio/FreeBSD/unlocked.c new file mode 100644 index 0000000..6b1c0ef --- /dev/null +++ b/stdio/FreeBSD/unlocked.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.c b/stdio/FreeBSD/vasprintf.c similarity index 83% rename from stdio/vasprintf.c rename to stdio/FreeBSD/vasprintf.c index 0937701..197c427 100644 --- a/stdio/vasprintf.c +++ b/stdio/FreeBSD/vasprintf.c @@ -27,22 +27,23 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(LIBC_RCS) && !defined(lint) -static char rcsid[] = "$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.11 1999/08/28 00:01:19 peter Exp $"; -#endif /* LIBC_RCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.18 2002/09/26 13:11:24 tjr Exp $"); #include #include #include +#include "local.h" int vasprintf(str, fmt, ap) char **str; const char *fmt; - _BSD_VA_LIST_ ap; + __va_list ap; { int ret; FILE f; + struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR | __SALC; @@ -52,14 +53,17 @@ vasprintf(str, fmt, ap) errno = ENOMEM; return (-1); } - f._bf._size = f._w = 127; /* Leave room for the NULL */ - ret = vfprintf(&f, fmt, ap); - *f._p = '\0'; - f._bf._base = reallocf(f._bf._base, f._bf._size + 1); - if (f._bf._base == NULL) { + f._bf._size = f._w = 127; /* Leave room for the NUL */ + f._extra = &ext; + INITEXTRA(&f); + ret = __vfprintf(&f, fmt, ap); + if (ret < 0) { + free(f._bf._base); + *str = NULL; errno = ENOMEM; - ret = -1; + return (-1); } + *f._p = '\0'; *str = (char *)f._bf._base; return (ret); } diff --git a/stdio/vfprintf.c b/stdio/FreeBSD/vfprintf.c similarity index 50% rename from stdio/vfprintf.c rename to stdio/FreeBSD/vfprintf.c index eb485ac..e615301 100644 --- a/stdio/vfprintf.c +++ b/stdio/FreeBSD/vfprintf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,96 +34,99 @@ * 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.59 2003/04/19 23:53:19 das Exp $"); + /* * Actual printf innards. * * This code is large and complicated... */ +#include "namespace.h" #include +#include #include +#include +#include +#include #include #include #include -#include +#include -#if __STDC__ #include -#else -#include -#endif +#include "un-namespace.h" +#include "libc_private.h" #include "local.h" #include "fvwrite.h" /* Define FLOATING_POINT to get floating point. */ #define FLOATING_POINT + union arg { - int intarg; - unsigned int uintarg; - long longarg; - unsigned long ulongarg; - quad_t quadarg; - u_quad_t uquadarg; - void *pvoidarg; - char *pchararg; - short *pshortarg; - int *pintarg; - long *plongarg; - quad_t *pquadarg; + 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; #ifdef FLOATING_POINT - double doublearg; - long double longdoublearg; -#endif -#ifdef ALTIVEC - 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]; + double doublearg; + long double longdoublearg; #endif + wint_t wintarg; + wchar_t *pwchararg; }; -static int __sprint __P((FILE *, struct __suio *)); -static int __sbprintf __P((FILE *, const char *, va_list)); -static char * __ultoa __P((u_long, char *, int, int, char *)); -static char * __uqtoa __P((u_quad_t, char *, int, int, char *)); -static void __find_arguments __P((const char *, va_list, union arg **)); -static void __grow_type_table __P((int, unsigned char **, int *)); - - /* - * 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))) - -#ifdef ALTIVEC -static void getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap) -{ - vector unsigned char tmp; - - tmp = GETARG(vector unsigned char); - memcpy( dst, &tmp, 16 ); -} +/* + * 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, + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR +}; -#endif +static int __sprint(FILE *, struct __suio *); +static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0); +static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char, + const char *); +static char *__ultoa(u_long, char *, int, int, const char *, int, char, + const char *); +static char *__wcsconv(wchar_t *, int); +static void __find_arguments(const char *, va_list, union arg **); +static void __grow_type_table(int, enum typeid **, int *); /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ static int -__sprint(fp, uio) - FILE *fp; - register struct __suio *uio; +__sprint(FILE *fp, struct __suio *uio) { - register int err; + int err; if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; @@ -165,10 +144,7 @@ __sprint(fp, uio) * worries about ungetc buffers and so forth. */ static int -__sbprintf(fp, fmt, ap) - register FILE *fp; - const char *fmt; - va_list ap; +__sbprintf(FILE *fp, const char *fmt, va_list ap) { int ret; FILE fake; @@ -179,6 +155,7 @@ __sbprintf(fp, fmt, ap) 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; @@ -186,8 +163,8 @@ __sbprintf(fp, fmt, ap) fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ - ret = vfprintf(&fake, fmt, ap); - if (ret >= 0 && fflush(&fake)) + ret = __vfprintf(&fake, fmt, ap); + if (ret >= 0 && __fflush(&fake)) ret = EOF; if (fake._flags & __SERR) fp->_flags |= __SERR; @@ -208,14 +185,12 @@ __sbprintf(fp, fmt, ap) * use the given digits. */ static char * -__ultoa(val, endp, base, octzero, xdigs) - register u_long val; - char *endp; - int base, octzero; - char *xdigs; +__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs, + int needgrp, char thousep, const char *grp) { - register char *cp = endp; - register long sval; + char *cp = endp; + long sval; + int ndig; /* * Handle the three cases separately, in the hope of getting @@ -227,6 +202,7 @@ __ultoa(val, endp, base, octzero, xdigs) *--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 @@ -235,11 +211,29 @@ __ultoa(val, endp, base, octzero, xdigs) */ 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; @@ -266,34 +260,52 @@ __ultoa(val, endp, base, octzero, xdigs) return (cp); } -/* Identical to __ultoa, but for quads. */ +/* Identical to __ultoa, but for intmax_t. */ static char * -__uqtoa(val, endp, base, octzero, xdigs) - register u_quad_t val; - char *endp; - int base, octzero; - char *xdigs; +__ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, + int needgrp, char thousep, const char *grp) { - register char *cp = endp; - register quad_t sval; + 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)); + 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); } - if (val > QUAD_MAX) { + 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; @@ -320,97 +332,195 @@ __uqtoa(val, endp, base, octzero, xdigs) return (cp); } -#ifdef FLOATING_POINT -#include -#include "floatio.h" +/* + * 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) +{ + char buf[MB_LEN_MAX]; + wchar_t *p; + char *convbuf, *mbp; + size_t clen, nbytes; + mbstate_t mbs; -#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ -#define DEFPREC 6 + /* + * Determine the number of bytes to output and allocate space for + * the output. + */ + memset(&mbs, 0, sizeof(mbs)); + if (prec >= 0) { + nbytes = 0; + p = wcsarg; + for (;;) { + clen = wcrtomb(buf, *p++, &mbs); + if (clen == 0 || clen == (size_t)-1 || + nbytes + clen > prec) + break; + nbytes += clen; + } + } else { + p = wcsarg; + nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs); + if (nbytes == (size_t)-1) + return (NULL); + } + if ((convbuf = malloc(nbytes + 1)) == NULL) + return (NULL); -static char *cvt __P((double, int, int, char *, int *, int, int *, char **)); -static int exponent __P((char *, int, int)); + /* + * Fill the output buffer with the multibyte representations of as + * many wide characters as will fit. + */ + mbp = convbuf; + p = wcsarg; + memset(&mbs, 0, sizeof(mbs)); + while (mbp - convbuf < nbytes) { + clen = wcrtomb(mbp, *p++, &mbs); + if (clen == 0 || clen == (size_t)-1) + break; + mbp += clen; + } + if (clen == (size_t)-1) { + free(convbuf); + return (NULL); + } + *mbp = '\0'; + + return (convbuf); +} -#if defined(__APPLE__) /* - * We don't want to be dependent on any libm symbols so use the versions in Libc + * MT-safe version */ +int +vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) -#undef isinf -#undef isnan +{ + int ret; -extern int isnan(double); -extern int isinf(double); + FLOCKFILE(fp); + ret = __vfprintf(fp, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); +} -#endif /* __APPLE __ */ +#ifdef FLOATING_POINT -#else /* no FLOATING_POINT */ +#define dtoa __dtoa +#define freedtoa __freedtoa -#define BUF 68 +#include +#include +#include "floatio.h" +#include "gdtoa.h" + +#define DEFPREC 6 + +static int exponent(char *, int, int); #endif /* 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 HEXPREFIX 0x002 /* add 0x or 0X prefix */ #define LADJUST 0x004 /* left adjustment */ #define LONGDBL 0x008 /* long double */ #define LONGINT 0x010 /* long integer */ -#define QUADINT 0x020 /* quad 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 VECTOR 0x200 /* Altivec vector */ +#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 */ + +/* + * Non-MT-safe version + */ int -vfprintf(fp, fmt0, ap) - FILE *fp; - const char *fmt0; - va_list ap; +__vfprintf(FILE *fp, const char *fmt0, va_list ap) { - register char *fmt; /* format string */ - register int ch; /* character from fmt */ - register int n, n2; /* handy integer (short term usage) */ - register char *cp; /* handy char pointer (short term usage) */ - register struct __siov *iovp;/* for PRINT macro */ - register int flags; /* flags as above */ + 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 (%.3d), or -1 */ + 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 */ #ifdef FLOATING_POINT - char softsign; /* temporary negative sign for floats */ - double _double = 0; /* double precision arguments %[eEfgG] */ + /* + * 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 */ - int expsize = 0; /* character count for expstr */ - int ndig; /* actual number of digits returned by cvt */ - char expstr[7]; /* buffer for exponent string */ + 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 ALTIVEC - union arg vval; /* Vector argument. */ - char *pct; /* Pointer to '%' at beginning of specifier. */ - char vsep; /* Vector separator character. */ -#endif - u_long ulval = 0; /* integer arguments %[diouxX] */ - u_quad_t uqval = 0; /* %q integers */ + 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 */ - char *xdigs = NULL; /* digits for [xX] conversion */ + 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]; /* space for %c, %[diouxX], %[eEfgG] */ - char 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 */ + 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 @@ -423,6 +533,9 @@ vfprintf(fp, fmt0, ap) 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'. */ @@ -446,6 +559,14 @@ vfprintf(fp, fmt0, ap) 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; \ @@ -453,6 +574,14 @@ vfprintf(fp, fmt0, ap) 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 @@ -461,57 +590,71 @@ vfprintf(fp, fmt0, ap) #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(size_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. - */ + /* + * 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 { \ + 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; #ifdef FLOATING_POINT dtoaresult = NULL; + decimal_point = localeconv()->decimal_point; #endif - /* FLOCKFILE(fp); */ /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ - if (cantwrite(fp)) { - /* FUNLOCKFILE(fp); */ + if (cantwrite(fp)) return (EOF); - } /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) { - /* FUNLOCKFILE(fp); */ + fp->_file >= 0) return (__sbprintf(fp, fmt0, ap)); - } fmt = (char *)fmt0; - argtable = NULL; - nextarg = 1; - orgap = ap; + argtable = NULL; + nextarg = 1; + va_copy(orgap, ap); uio.uio_iov = iovp = iov; uio.uio_resid = 0; uio.uio_iovcnt = 0; @@ -533,9 +676,6 @@ vfprintf(fp, fmt0, ap) } if (ch == '\0') goto done; -#ifdef ALTIVEC - pct = fmt; -#endif fmt++; /* skip over '%' */ flags = 0; @@ -543,14 +683,12 @@ vfprintf(fp, fmt0, ap) width = 0; prec = -1; sign = '\0'; -#ifdef ALTIVEC - vsep = 'X'; /* Illegal value, changed to defaults later. */ -#endif + ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': - /* + /*- * ``If the space and + flags both appear, the space * flag will be ignored.'' * -- ANSI X3J11 @@ -561,13 +699,8 @@ reswitch: switch (ch) { case '#': flags |= ALT; goto rflag; -#ifdef ALTIVEC - case ',': case ';': case ':': case '_': - vsep = ch; - goto rflag; -#endif case '*': - /* + /*- * ``A negative field width argument is taken as a * - flag followed by a positive field width.'' * -- ANSI X3J11 @@ -584,21 +717,24 @@ reswitch: switch (ch) { case '+': sign = '+'; goto rflag; + case '\'': + flags |= GROUPING; + thousands_sep = *(localeconv()->thousands_sep); + grouping = localeconv()->grouping; + goto rflag; case '.': if ((ch = *fmt++) == '*') { - GETASTER (n); - prec = n < 0 ? -1 : n; + GETASTER (prec); goto rflag; } - n = 0; + prec = 0; while (is_digit(ch)) { - n = 10 * n + to_digit(ch); + prec = 10 * prec + to_digit(ch); ch = *fmt++; } - prec = n < 0 ? -1 : n; goto reswitch; case '0': - /* + /*- * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 @@ -614,53 +750,66 @@ reswitch: switch (ch) { } while (is_digit(ch)); if (ch == '$') { nextarg = n; - if (argtable == NULL) { - argtable = statargtable; - __find_arguments (fmt0, orgap, - &argtable); + if (argtable == NULL) { + argtable = statargtable; + __find_arguments (fmt0, orgap, + &argtable); } goto rflag; - } + } width = n; goto reswitch; #ifdef FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; -#endif -#ifdef ALTIVEC - case 'v': - flags |= VECTOR; - goto rflag; #endif case 'h': - flags |= SHORTINT; + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; goto rflag; case 'l': - if (flags & LONGINT) - flags |= QUADINT; - else + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else flags |= LONGINT; goto rflag; case 'q': - flags |= QUADINT; + flags |= LLONGINT; /* not necessarily */ + goto rflag; + case 't': + flags |= PTRDIFFT; goto rflag; case 'z': - if (sizeof(size_t) == sizeof(long)) - flags |= LONGINT; - if (sizeof(size_t) == sizeof(quad_t)) - flags |= QUADINT; + flags |= SIZET; goto rflag; + case 'C': + flags |= LONGINT; + /*FALLTHROUGH*/ case 'c': -#ifdef ALTIVEC - if (flags & VECTOR) { - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; + if (flags & LONGINT) { + mbstate_t mbs; + size_t mbseqlen; + + memset(&mbs, 0, sizeof(mbs)); + mbseqlen = wcrtomb(cp = buf, + (wchar_t)GETARG(wint_t), &mbs); + if (mbseqlen == (size_t)-1) { + fp->_flags |= __SERR; + goto error; + } + size = (int)mbseqlen; + } else { + *(cp = buf) = GETARG(int); + size = 1; } -#endif - *(cp = buf) = GETARG(int); - size = 1; sign = '\0'; break; case 'D': @@ -668,16 +817,10 @@ reswitch: switch (ch) { /*FALLTHROUGH*/ case 'd': case 'i': -#ifdef ALTIVEC - if (flags & VECTOR) { - getvec(&vval, argtable, nextarg, ap); - break; - } else -#endif - if (flags & QUADINT) { - uqval = GETARG(quad_t); - if ((quad_t)uqval < 0) { - uqval = -uqval; + if (flags & INTMAX_SIZE) { + ujval = SJARG(); + if ((intmax_t)ujval < 0) { + ujval = -ujval; sign = '-'; } } else { @@ -690,95 +833,156 @@ reswitch: switch (ch) { base = 10; goto number; #ifdef FLOATING_POINT +#ifdef HEXFLOAT + case 'a': + case 'A': + if (ch == 'a') { + ox[1] = 'x'; + xdigs = xdigs_lower; + expchar = 'p'; + } else { + ox[1] = 'X'; + xdigs = xdigs_upper; + expchar = 'P'; + } + /* + * XXX We don't actually have a conversion + * XXX routine for this yet. + */ + if (flags & LONGDBL) { + fparg.ldbl = (double)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); + } + goto fp_begin; +#endif case 'e': case 'E': + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; + else + prec++; + goto fp_begin; case 'f': -#ifdef ALTIVEC - if (flags & VECTOR) { - flags |= FPT; - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; - } -#endif + case 'F': + expchar = '\0'; goto fp_begin; case 'g': case 'G': -#ifdef ALTIVEC - if (flags & VECTOR) { - flags |= FPT; - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; - } -#endif + expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; -fp_begin: if (prec == -1) +fp_begin: + if (prec < 0) prec = DEFPREC; - if (flags & LONGDBL) - /* XXX this loses precision. */ - _double = (double)GETARG(long double); - else - _double = GETARG(double); - /* do this before tricky precision changes */ - if (isinf(_double)) { - if (_double < 0) - sign = '-'; - cp = "Inf"; - size = 3; - break; + if (dtoaresult != NULL) + freedtoa(dtoaresult); + 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; } - if (isnan(_double)) { - cp = "NaN"; + 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; - if (dtoaresult != NULL) { - free(dtoaresult); - dtoaresult = NULL; - } - cp = cvt(_double, prec, flags, &softsign, - &expt, ch, &ndig, &dtoaresult); + ndig = dtoaend - cp; if (ch == 'g' || ch == 'G') { - if (expt <= -4 || expt > prec) - ch = (ch == 'g') ? 'e' : 'E'; - else - 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 (ch <= 'e') { /* 'e' or 'E' fmt */ - --expt; - expsize = exponent(expstr, expt, ch); - size = expsize + ndig; - if (ndig > 1 || flags & ALT) + if (expchar) { + expsize = exponent(expstr, expt - 1, expchar); + size = expsize + prec; + if (prec > 1 || flags & ALT) ++size; - } else if (ch == 'f') { /* f fmt */ - if (expt > 0) { + } else { + /* space for digits before decimal point */ + if (expt > 0) size = expt; - if (prec || flags & ALT) - size += prec + 1; - } else /* "0.X" */ - size = prec + 2; - } else if (expt >= ndig) { /* fixed g fmt */ - size = expt; - if (flags & ALT) - ++size; - } else - size = ndig + (expt > 0 ? - 1 : 2 - expt); - - if (softsign) - sign = '-'; + 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 /* FLOATING_POINT */ case 'n': - if (flags & QUADINT) - *GETARG(quad_t *) = ret; + /* + * 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 */ @@ -786,42 +990,46 @@ fp_begin: if (prec == -1) flags |= LONGINT; /*FALLTHROUGH*/ case 'o': -#ifdef ALTIVEC - if (flags & VECTOR) { - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; - } else -#endif - if (flags & QUADINT) - uqval = GETARG(u_quad_t); + 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 ALTIVEC - if (flags & VECTOR) { - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; - } -#endif - ulval = (u_long)GETARG(void *); + ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; - xdigs = "0123456789abcdef"; - flags = (flags & ~QUADINT) | HEXPREFIX; - ch = 'x'; + xdigs = xdigs_lower; + flags = flags | INTMAXT; + ox[1] = 'x'; goto nosign; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ case 's': - if ((cp = GETARG(char *)) == NULL) + if (flags & LONGINT) { + wchar_t *wcp; + + if (convbuf != NULL) + free(convbuf); + if ((wcp = GETARG(wchar_t *)) == NULL) + cp = "(null)"; + else { + convbuf = __wcsconv(wcp, prec); + if (convbuf == NULL) { + fp->_flags |= __SERR; + goto error; + } + cp = convbuf; + } + } else if ((cp = GETARG(char *)) == NULL) cp = "(null)"; if (prec >= 0) { /* @@ -845,45 +1053,32 @@ fp_begin: if (prec == -1) flags |= LONGINT; /*FALLTHROUGH*/ case 'u': -#ifdef ALTIVEC - if (flags & VECTOR) { - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; - } else -#endif - if (flags & QUADINT) - uqval = GETARG(u_quad_t); + if (flags & INTMAX_SIZE) + ujval = UJARG(); else ulval = UARG(); base = 10; goto nosign; case 'X': - xdigs = "0123456789ABCDEF"; + xdigs = xdigs_upper; goto hex; case 'x': - xdigs = "0123456789abcdef"; + xdigs = xdigs_lower; hex: -#ifdef ALTIVEC - if (flags & VECTOR) { - getvec(&vval, argtable, nextarg, ap); - nextarg++; - break; - } else -#endif - if (flags & QUADINT) - uqval = GETARG(u_quad_t); + if (flags & INTMAX_SIZE) + ujval = UJARG(); else ulval = UARG(); base = 16; /* leading 0x/X only if non-zero */ if (flags & ALT && - (flags & QUADINT ? uqval != 0 : ulval != 0)) - flags |= HEXPREFIX; + (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 @@ -891,22 +1086,28 @@ nosign: sign = '\0'; 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 */ cp = buf + BUF; - if (flags & QUADINT) { - if (uqval != 0 || prec != 0) - cp = __uqtoa(uqval, cp, base, - flags & ALT, xdigs); + 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) cp = __ultoa(ulval, cp, base, - flags & ALT, xdigs); + flags & ALT, xdigs, + flags & GROUPING, thousands_sep, + grouping); } size = buf + BUF - cp; + if (size > BUF) /* should never happen */ + abort(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') @@ -919,180 +1120,6 @@ number: if ((dprec = prec) >= 0) break; } -#ifdef ALTIVEC - 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. */ - char vfmt_buf[32]; /* Static buffer for format spec. */ - int vwidth = 0; /* Width specified via '*'. */ - int vprec = 0; /* Precision specified via '*'. */ - union { /* Element. */ - int i; - float f; - } velm; - char *vstr; /* Used for asprintf(). */ - int vlen; /* Length returned by asprintf(). */ - - /* - * Set vfmt. If vfmt_buf may not be big enough, - * malloc() space, taking care to free it later. - */ - if (&fmt[-1] - pct < sizeof(vfmt_buf)) - vfmt = vfmt_buf; - else - vfmt = (char *)malloc(&fmt[-1] - pct + 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) { - vfmt[j++] = 'h'; - vcnt = 8; - } else if (flags & LONGINT) { - vfmt[j++] = 'l'; - vcnt = 4; - } else { - switch (ch) { - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - vcnt = 4; - break; - default: - /* - * The default case should never - * happen. - */ - case 'c': - case 'd': - case 'i': - case 'u': - case 'o': - case 'p': - case 'x': - case 'X': - vcnt = 16; - } - } - vfmt[j++] = ch; - vfmt[j++] = '\0'; - -/* Get a vector element. */ -#define VPRINT(cnt, ind, args...) do { \ - if (flags & FPT) { \ - velm.f = vval.vfloatarg[ind]; \ - vlen = asprintf(&vstr, vfmt , ## args, velm.f); \ - } else { \ - switch (cnt) { \ - default: \ - /* The default case should never happen. */ \ - case 4: \ - velm.i = vval.vintarg[ind]; \ - break; \ - case 8: \ - velm.i = vval.vshortarg[ind]; \ - break; \ - case 16: \ - velm.i = vval.vchararg[ind]; \ - break; \ - } \ - vlen = asprintf(&vstr, vfmt , ## args, velm.i); \ - } \ - ret += vlen; \ - PRINT(vstr, vlen); \ - FLUSH(); \ - free(vstr); \ -} while (0) - - /* Actually print. */ - if (vwidth == 0) { - if (vprec == 0) { - /* First element. */ - VPRINT(vcnt, 0); - for (i = 1; i < vcnt; i++) { - /* Separator. */ - PRINT(&vsep, 1); - - /* Element. */ - VPRINT(vcnt, i); - } - } else { - /* First element. */ - VPRINT(vcnt, 0, prec); - for (i = 1; i < vcnt; i++) { - /* Separator. */ - PRINT(&vsep, 1); - - /* Element. */ - VPRINT(vcnt, i, prec); - } - } - } else { - if (vprec == 0) { - /* First element. */ - VPRINT(vcnt, 0, width); - for (i = 1; i < vcnt; i++) { - /* Separator. */ - PRINT(&vsep, 1); - - /* Element. */ - VPRINT(vcnt, i, width); - } - } else { - /* First element. */ - VPRINT(vcnt, 0, width, prec); - for (i = 1; i < vcnt; i++) { - /* Separator. */ - PRINT(&vsep, 1); - - /* Element. */ - VPRINT(vcnt, i, width, prec); - } - } - } -#undef VPRINT - - if (vfmt != vfmt_buf) - free(vfmt); - - continue; - } -#endif /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be @@ -1110,7 +1137,7 @@ number: if ((dprec = prec) >= 0) realsz = dprec > size ? dprec : size; if (sign) realsz++; - else if (flags & HEXPREFIX) + else if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; @@ -1126,9 +1153,8 @@ number: if ((dprec = prec) >= 0) /* prefix */ if (sign) { PRINT(&sign, 1); - } else if (flags & HEXPREFIX) { + } else if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; - ox[1] = ch; PRINT(ox, 2); } @@ -1144,41 +1170,45 @@ number: if ((dprec = prec) >= 0) if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ - if (ch >= 'f') { /* 'f' or 'g' */ - if (_double == 0) { - /* kludge for __dtoa irregularity */ - if (expt >= ndig && - (flags & ALT) == 0) { - PRINT("0", 1); - } else { - PRINT("0.", 2); - PAD(ndig - 1, zeroes); - } - } else if (expt <= 0) { - PRINT("0.", 2); + if (!expchar) { /* %[fF] or sufficiently short %[gG] */ + if (expt <= 0) { + PRINT(zeroes, 1); + if (prec || flags & ALT) + PRINT(decimal_point, 1); PAD(-expt, zeroes); - PRINT(cp, ndig); - } else if (expt >= ndig) { - PRINT(cp, ndig); - PAD(expt - ndig, zeroes); - if (flags & ALT) - PRINT(".", 1); + /* already handled initial 0's */ + prec += expt; } else { - PRINT(cp, expt); - cp += expt; - PRINT(".", 1); - PRINT(cp, ndig-expt); + 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,1); } - } else { /* 'e' or 'E' */ - if (ndig > 1 || flags & ALT) { - ox[0] = *cp++; - ox[1] = '.'; - PRINT(ox, 2); - if (_double) { - PRINT(cp, ndig-1); - } else /* 0.[0..] */ - /* __dtoa irregularity */ - PAD(ndig - 1, zeroes); + PRINTANDPAD(cp, dtoaend, prec, zeroes); + } else { /* %[eE] or sufficiently long %[gG] */ + if (prec > 1 || flags & ALT) { + buf[0] = *cp++; + buf[1] = *decimal_point; + PRINT(buf, 2); + PRINT(cp, ndig-1); + PAD(prec - ndig, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); @@ -1187,7 +1217,6 @@ number: if ((dprec = prec) >= 0) #else PRINT(cp, size); #endif - /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); @@ -1202,39 +1231,18 @@ done: error: #ifdef FLOATING_POINT if (dtoaresult != NULL) - free(dtoaresult); + freedtoa(dtoaresult); #endif + if (convbuf != NULL) + free(convbuf); if (__sferror(fp)) ret = EOF; - /* FUNLOCKFILE(fp); */ - if ((argtable != NULL) && (argtable != statargtable)) - free (argtable); + if ((argtable != NULL) && (argtable != statargtable)) + free (argtable); return (ret); /* NOTREACHED */ } -/* - * Type ids for argument type table. - */ -#define T_UNUSED 0 -#define T_SHORT 1 -#define T_U_SHORT 2 -#define TP_SHORT 3 -#define T_INT 4 -#define T_U_INT 5 -#define TP_INT 6 -#define T_LONG 7 -#define T_U_LONG 8 -#define TP_LONG 9 -#define T_QUAD 10 -#define T_U_QUAD 11 -#define TP_QUAD 12 -#define T_DOUBLE 13 -#define T_LONG_DOUBLE 14 -#define TP_CHAR 15 -#define TP_VOID 16 -#define T_VECTOR 17 - /* * Find all arguments when a positional parameter is encountered. Returns a * table, indexed by argument number, of pointers to each arguments. The @@ -1242,19 +1250,16 @@ error: * It will be replaces with a malloc-ed one if it overflows. */ static void -__find_arguments (fmt0, ap, argtable) - const char *fmt0; - va_list ap; - union arg **argtable; +__find_arguments (const char *fmt0, va_list ap, union arg **argtable) { - register char *fmt; /* format string */ - register int ch; /* character from fmt */ - register int n, n2; /* handy integer (short term usage) */ - register char *cp; /* handy char pointer (short term usage) */ - register int flags; /* flags as above */ + 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 */ - unsigned char *typetable; /* table of types */ - unsigned char stattypetable [STATIC_ARG_TBL_SIZE]; + 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 */ @@ -1269,12 +1274,18 @@ __find_arguments (fmt0, ap, argtable) typetable[nextarg++] = type) #define ADDSARG() \ - ((flags&LONGINT) ? ADDTYPE(T_LONG) : \ - ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT))) + ((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&LONGINT) ? ADDTYPE(T_U_LONG) : \ - ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT))) + ((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. @@ -1325,6 +1336,7 @@ reswitch: switch (ch) { goto rflag; case '-': case '+': + case '\'': goto rflag; case '.': if ((ch = *fmt++) == '*') { @@ -1356,23 +1368,38 @@ reswitch: switch (ch) { goto rflag; #endif case 'h': - flags |= SHORTINT; + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; goto rflag; case 'l': - if (flags & LONGINT) - flags |= QUADINT; - else + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else flags |= LONGINT; goto rflag; case 'q': - flags |= QUADINT; + 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 ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); + if (flags & LONGINT) + ADDTYPE(T_WINT); else -#endif ADDTYPE(T_INT); break; case 'D': @@ -1380,28 +1407,18 @@ reswitch: switch (ch) { /*FALLTHROUGH*/ case 'd': case 'i': -#ifdef ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif - if (flags & QUADINT) { - ADDTYPE(T_QUAD); - } else { - ADDSARG(); - } + ADDSARG(); break; #ifdef FLOATING_POINT +#ifdef HEXFLOAT + case 'a': + case 'A': +#endif case 'e': case 'E': case 'f': case 'g': case 'G': -#ifdef ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else @@ -1409,12 +1426,20 @@ reswitch: switch (ch) { break; #endif /* FLOATING_POINT */ case 'n': - if (flags & QUADINT) - ADDTYPE(TP_QUAD); + 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 */ @@ -1422,52 +1447,27 @@ reswitch: switch (ch) { flags |= LONGINT; /*FALLTHROUGH*/ case 'o': -#ifdef ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif - if (flags & QUADINT) - ADDTYPE(T_U_QUAD); - else - ADDUARG(); + ADDUARG(); break; case 'p': -#ifdef ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif - ADDTYPE(TP_VOID); + ADDTYPE(TP_VOID); break; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ case 's': - ADDTYPE(TP_CHAR); + if (flags & LONGINT) + ADDTYPE(TP_WCHAR); + else + ADDTYPE(TP_CHAR); break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': -#ifdef ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif - if (flags & QUADINT) - ADDTYPE(T_U_QUAD); - else - ADDUARG(); - break; case 'X': case 'x': -#ifdef ALTIVEC - if (flags & VECTOR) - ADDTYPE(T_VECTOR); - else -#endif - if (flags & QUADINT) - ADDTYPE(T_U_QUAD); - else - ADDUARG(); + ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') @@ -1484,17 +1484,14 @@ done: malloc (sizeof (union arg) * (tablemax + 1)); } - (*argtable) [0].intarg = NULL; + (*argtable) [0].intarg = 0; for (n = 1; n <= tablemax; n++) { switch (typetable [n]) { - case T_UNUSED: - (*argtable) [n].intarg = va_arg (ap, int); - break; - case T_SHORT: + case T_UNUSED: /* whoops! */ (*argtable) [n].intarg = va_arg (ap, int); break; - case T_U_SHORT: - (*argtable) [n].intarg = va_arg (ap, int); + case TP_SCHAR: + (*argtable) [n].pschararg = va_arg (ap, signed char *); break; case TP_SHORT: (*argtable) [n].pshortarg = va_arg (ap, short *); @@ -1517,14 +1514,35 @@ done: case TP_LONG: (*argtable) [n].plongarg = va_arg (ap, long *); break; - case T_QUAD: - (*argtable) [n].quadarg = va_arg (ap, quad_t); + case T_LLONG: + (*argtable) [n].longlongarg = va_arg (ap, long long); + break; + case T_U_LLONG: + (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); + break; + case TP_LLONG: + (*argtable) [n].plonglongarg = va_arg (ap, long long *); + break; + case T_PTRDIFFT: + (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); + break; + case TP_PTRDIFFT: + (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); + break; + case T_SIZET: + (*argtable) [n].sizearg = va_arg (ap, size_t); + break; + case TP_SIZET: + (*argtable) [n].psizearg = va_arg (ap, ssize_t *); + break; + case T_INTMAXT: + (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); break; - case T_U_QUAD: - (*argtable) [n].uquadarg = va_arg (ap, u_quad_t); + case T_UINTMAXT: + (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); break; - case TP_QUAD: - (*argtable) [n].pquadarg = va_arg (ap, quad_t *); + case TP_INTMAXT: + (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); break; #ifdef FLOATING_POINT case T_DOUBLE: @@ -1533,12 +1551,6 @@ done: case T_LONG_DOUBLE: (*argtable) [n].longdoublearg = va_arg (ap, long double); break; -#endif -#ifdef ALTIVEC - case T_VECTOR: - { int tmp = 0; - getvec( &((*argtable) [n]), NULL, tmp, ap ); - } #endif case TP_CHAR: (*argtable) [n].pchararg = va_arg (ap, char *); @@ -1546,6 +1558,12 @@ done: 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; } } @@ -1557,27 +1575,24 @@ done: * Increase the size of the type table. */ static void -__grow_type_table (nextarg, typetable, tablesize) - int nextarg; - unsigned char **typetable; - int *tablesize; +__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) { - unsigned char *const oldtable = *typetable; + enum typeid *const oldtable = *typetable; const int oldsize = *tablesize; - unsigned char *newtable; + enum typeid *newtable; int newsize = oldsize * 2; if (newsize < nextarg + 1) newsize = nextarg + 1; if (oldsize == STATIC_ARG_TBL_SIZE) { - if ((newtable = malloc (newsize)) == NULL) - abort(); /* XXX handle better */ - bcopy (oldtable, newtable, oldsize); + if ((newtable = malloc(newsize)) == NULL) + abort(); /* XXX handle better */ + bcopy(oldtable, newtable, oldsize); } else { - if ((newtable = realloc (oldtable, newsize)) == NULL) - abort(); /* XXX handle better */ + if ((newtable = reallocf(oldtable, newsize)) == NULL) + abort(); /* XXX handle better */ } - memset (&newtable [oldsize], T_UNUSED, (newsize - oldsize)); + memset(&newtable[oldsize], T_UNUSED, newsize - oldsize); *typetable = newtable; *tablesize = newsize; @@ -1586,60 +1601,11 @@ __grow_type_table (nextarg, typetable, tablesize) #ifdef FLOATING_POINT -extern char *__dtoa __P((double, int, int, int *, int *, char **, char **)); - -static char * -cvt(value, ndigits, flags, sign, decpt, ch, length, dtoaresultp) - double value; - int ndigits, flags, *decpt, ch, *length; - char *sign; - char **dtoaresultp; -{ - int mode, dsgn; - char *digits, *bp, *rve; - - if (ch == 'f') - mode = 3; /* ndigits after the decimal point */ - else { - /* - * To obtain ndigits after the decimal point for the 'e' - * and 'E' formats, round to ndigits + 1 significant - * figures. - */ - if (ch == 'e' || ch == 'E') - ndigits++; - mode = 2; /* ndigits significant digits */ - } - if (value < 0) { - value = -value; - *sign = '-'; - } else - *sign = '\000'; - digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve, dtoaresultp); - if ((ch != 'g' && ch != 'G') || flags & ALT) { - /* print trailing zeros */ - bp = digits + ndigits; - if (ch == 'f') { - if (*digits == '0' && value) - *decpt = -ndigits + 1; - bp += *decpt; - } - if (value == 0) /* kludge for __dtoa irregularity */ - rve = bp; - while (rve < bp) - *rve++ = '0'; - } - *length = rve - digits; - return (digits); -} - static int -exponent(p0, exp, fmtch) - char *p0; - int exp, fmtch; +exponent(char *p0, int exp, int fmtch) { - register char *p, *t; - char expbuf[MAXEXP]; + char *p, *t; + char expbuf[MAXEXPDIG]; p = p0; *p++ = fmtch; @@ -1649,16 +1615,23 @@ exponent(p0, exp, fmtch) } else *p++ = '+'; - t = expbuf + MAXEXP; + t = expbuf + MAXEXPDIG; if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); - for (; t < expbuf + MAXEXP; *p++ = *t++); + for (; t < expbuf + MAXEXPDIG; *p++ = *t++); } else { - *p++ = '0'; + /* + * 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); diff --git a/stdio/FreeBSD/vfprintf.c.patch b/stdio/FreeBSD/vfprintf.c.patch new file mode 100644 index 0000000..5b79cb3 --- /dev/null +++ b/stdio/FreeBSD/vfprintf.c.patch @@ -0,0 +1,718 @@ +--- vfprintf.c.orig Thu Jul 24 12:42:14 2003 ++++ vfprintf.c Sun Aug 24 16:21:44 2003 +@@ -66,9 +66,20 @@ + #include "local.h" + #include "fvwrite.h" + ++#ifdef ALTIVEC ++#include ++ ++#define VECTORTYPE vector unsigned char ++#endif /* ALTIVEC */ ++ + /* Define FLOATING_POINT to get floating point. */ + #define FLOATING_POINT + ++/* if no floating point, turn off HEXFLOAT as well */ ++#if defined(HEXFLOAT) && !defined(FLOATING_POINT) ++#undef HEXFLOAT ++#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */ ++ + union arg { + int intarg; + u_int uintarg; +@@ -88,7 +99,7 @@ + long *plongarg; + long long *plonglongarg; + ptrdiff_t *pptrdiffarg; +- size_t *psizearg; ++ ssize_t *psizearg; + intmax_t *pintmaxarg; + #ifdef FLOATING_POINT + double doublearg; +@@ -96,6 +107,16 @@ + #endif + wint_t wintarg; + wchar_t *pwchararg; ++#ifdef ALTIVEC ++ 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]; ++#endif /* ALTIVEC */ + }; + + /* +@@ -106,7 +127,11 @@ + 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 ALTIVEC ++ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR ++#else /* ! ALTIVEC */ + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR ++#endif /* ALTIVEC */ + }; + + static int __sprint(FILE *, struct __suio *); +@@ -119,6 +144,37 @@ + static void __find_arguments(const char *, va_list, union arg **); + static void __grow_type_table(int, enum typeid **, int *); + ++ /* ++ * 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))) ++ ++#ifdef ALTIVEC ++#define hasAltivec (_cpu_capabilities & kHasAltivec) ++/*----------------------------------------------------------------------- ++ * getvec() must be a real subroutine. If it is a #define, then __vfprintf() ++ * would have its calling sequence changed by Altivec so that a non-Altivec ++ * processor would crash on illegal instruction. By isolating the calling ++ * sequence in getvec(), __vprintf() is callable by a non-Altivec processor. ++ *-----------------------------------------------------------------------*/ ++static va_list ++getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap) ++{ ++ dst->vectorarg = GETARG(VECTORTYPE); ++ return ap; ++} ++ ++#define SETVEC(dst) \ ++{ \ ++ ap = getvec(&dst, argtable, nextarg, ap); \ ++ nextarg++; \ ++} ++#endif /* ALTIVEC */ ++ + /* + * Flush out all the vectors defined by the given uio, + * then reset it so that it can be reused. +@@ -424,6 +480,15 @@ + + #endif /* FLOATING_POINT */ + ++#ifdef HEXFLOAT ++extern int __hdtoa(double d, const char *xdigs, int prec, char *cp, ++ int *expt, int *signflag, char **dtoaend); ++#if !__TYPE_LONGDOUBLE_IS_DOUBLE ++extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp, ++ int *expt, int *signflag, char **dtoaend); ++#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */ ++#endif /* HEXFLOAT */ ++ + /* + * The size of the buffer we use as scratch space for integer + * conversions, among other things. Technically, we would need the +@@ -452,6 +517,9 @@ + #define PTRDIFFT 0x800 /* ptrdiff_t */ + #define INTMAXT 0x1000 /* intmax_t */ + #define CHARINT 0x2000 /* print char using int format */ ++#ifdef ALTIVEC ++#define VECTOR 0x4000 /* Altivec vector */ ++#endif /* ALTIVEC */ + + /* + * Non-MT-safe version +@@ -503,6 +571,11 @@ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ + #endif ++#ifdef ALTIVEC ++ 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 */ +@@ -535,6 +608,12 @@ + + static const char xdigs_lower[16] = "0123456789abcdef"; + static const char xdigs_upper[16] = "0123456789ABCDEF"; ++#ifdef HEXFLOAT ++#define HEXFLOATDELTA 32 ++#define HEXFLOATSTART 32 ++ static char *hexfloat = NULL; ++ static int hexfloatlen = 0; ++#endif /* HEXFLOAT */ + + /* + * BEWARE, these `goto error' on error, and PAD uses `n'. +@@ -575,15 +654,6 @@ + } + + /* +- * 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. + */ +@@ -634,7 +704,6 @@ + val = GETARG (int); \ + } + +- + thousands_sep = '\0'; + grouping = NULL; + convbuf = NULL; +@@ -676,6 +745,9 @@ + } + if (ch == '\0') + goto done; ++#ifdef ALTIVEC ++ pct = fmt; ++#endif /* ALTIVEC */ + fmt++; /* skip over '%' */ + + flags = 0; +@@ -684,6 +756,9 @@ + prec = -1; + sign = '\0'; + ox[1] = '\0'; ++#ifdef ALTIVEC ++ vsep = 'X'; /* Illegal value, changed to defaults later. */ ++#endif /* ALTIVEC */ + + rflag: ch = *fmt++; + reswitch: switch (ch) { +@@ -699,6 +774,11 @@ + case '#': + flags |= ALT; + goto rflag; ++#ifdef ALTIVEC ++ case ',': case ';': case ':': case '_': ++ vsep = ch; ++ goto rflag; ++#endif /* ALTIVEC */ + case '*': + /*- + * ``A negative field width argument is taken as a +@@ -807,6 +887,12 @@ + } + size = (int)mbseqlen; + } else { ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + *(cp = buf) = GETARG(int); + size = 1; + } +@@ -817,6 +903,12 @@ + /*FALLTHROUGH*/ + case 'd': + case 'i': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) { + ujval = SJARG(); + if ((intmax_t)ujval < 0) { +@@ -836,6 +928,13 @@ + #ifdef HEXFLOAT + case 'a': + case 'A': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + if (ch == 'a') { + ox[1] = 'x'; + xdigs = xdigs_lower; +@@ -845,25 +944,51 @@ + xdigs = xdigs_upper; + expchar = 'P'; + } +- /* +- * XXX We don't actually have a conversion +- * XXX routine for this yet. +- */ ++ if (!hexfloat) { ++ hexfloat = malloc(hexfloatlen = HEXFLOATSTART); ++ if (!hexfloat) ++ goto error; ++ } ++ if (prec > hexfloatlen - 1) { ++ int hlen = prec + HEXFLOATDELTA; ++ char *hf = realloc(hexfloat, hlen); ++ if (hf == NULL) ++ goto error; ++ hexfloat = hf; ++ hexfloatlen = hlen; ++ } ++ cp = hexfloat; + if (flags & LONGDBL) { +- fparg.ldbl = (double)GETARG(long double); +- dtoaresult = cp = +- __hldtoa(fparg.ldbl, xdigs, prec, ++#if __TYPE_LONGDOUBLE_IS_DOUBLE ++ fparg.dbl = (double)GETARG(long double); ++ prec = __hdtoa(fparg.dbl, xdigs, prec, cp, + &expt, &signflag, &dtoaend); ++#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ ++ fparg.ldbl = GETARG(long double); ++ prec = __hldtoa(fparg.ldbl, xdigs, prec, cp, ++ &expt, &signflag, &dtoaend); ++#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ + } else { + fparg.dbl = GETARG(double); +- dtoaresult = cp = +- __hdtoa(fparg.dbl, xdigs, prec, ++ prec = __hdtoa(fparg.dbl, xdigs, prec, cp, + &expt, &signflag, &dtoaend); + } +- goto fp_begin; ++ prec++; ++ if (expt == INT_MAX) ++ ox[1] = 0; ++ else ++ expt++; ++ goto hex_begin; + #endif + case 'e': + case 'E': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; +@@ -872,10 +997,24 @@ + goto fp_begin; + case 'f': + case 'F': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + expchar = '\0'; + goto fp_begin; + case 'g': + case 'G': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + expchar = ch - ('g' - 'e'); + if (prec == 0) + prec = 1; +@@ -884,6 +1023,17 @@ + prec = DEFPREC; + if (dtoaresult != NULL) + freedtoa(dtoaresult); ++#if __TYPE_LONGDOUBLE_IS_DOUBLE ++ if (flags & LONGDBL) ++ fparg.dbl = (double)GETARG(long double); ++ else ++ fparg.dbl = GETARG(double); ++ dtoaresult = cp = ++ dtoa(fparg.dbl, expchar ? 2 : 3, prec, ++ &expt, &signflag, &dtoaend); ++ if (expt == 9999) ++ expt = INT_MAX; ++#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = cp = +@@ -897,6 +1047,10 @@ + if (expt == 9999) + expt = INT_MAX; + } ++#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ ++#ifdef HEXFLOAT ++hex_begin: ++#endif /* HEXFLOAT */ + if (signflag) + sign = '-'; + if (expt == INT_MAX) { /* inf or nan */ +@@ -990,6 +1144,12 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else +@@ -1004,6 +1164,12 @@ + * defined manner.'' + * -- ANSI X3J11 + */ ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + ujval = (uintmax_t)(uintptr_t)GETARG(void *); + base = 16; + xdigs = xdigs_lower; +@@ -1053,6 +1219,12 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else +@@ -1065,6 +1237,12 @@ + case 'x': + xdigs = xdigs_lower; + hex: ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else +@@ -1109,6 +1287,14 @@ + if (size > BUF) /* should never happen */ + abort(); + break; ++#ifdef ALTIVEC ++ case 'v': ++ if (hasAltivec) { ++ flags |= VECTOR; ++ goto rflag; ++ } ++ /* drap through */ ++#endif /* ALTIVEC */ + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; +@@ -1120,6 +1306,186 @@ + break; + } + ++#ifdef ALTIVEC ++ 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. */ ++ char vfmt_buf[32]; /* Static buffer for format spec. */ ++ int vwidth = 0; /* Width specified via '*'. */ ++ int vprec = 0; /* Precision specified via '*'. */ ++ union { /* Element. */ ++ int i; ++ float f; ++ } velm; ++ char *vstr; /* Used for asprintf(). */ ++ int vlen; /* Length returned by asprintf(). */ ++ ++ /* ++ * Set vfmt. If vfmt_buf may not be big enough, ++ * malloc() space, taking care to free it later. ++ */ ++ if (&fmt[-1] - pct < sizeof(vfmt_buf)) ++ vfmt = vfmt_buf; ++ else ++ vfmt = (char *)malloc(&fmt[-1] - pct + 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) { ++ vfmt[j++] = 'h'; ++ vcnt = 8; ++ } else if (flags & LONGINT) { ++ vfmt[j++] = 'l'; ++ vcnt = 4; ++ } else { ++ switch (ch) { ++ case 'a': ++ case 'A': ++ case 'e': ++ case 'E': ++ case 'f': ++ case 'g': ++ case 'G': ++ vcnt = 4; ++ break; ++ default: ++ /* ++ * The default case should never ++ * happen. ++ */ ++ case 'c': ++ case 'd': ++ case 'i': ++ case 'u': ++ case 'o': ++ case 'p': ++ case 'x': ++ case 'X': ++ vcnt = 16; ++ } ++ } ++ vfmt[j++] = ch; ++ vfmt[j++] = '\0'; ++ ++/* Get a vector element. */ ++#define VPRINT(cnt, ind, args...) do { \ ++ if (flags & FPT) { \ ++ velm.f = vval.vfloatarg[ind]; \ ++ vlen = asprintf(&vstr, vfmt , ## args, velm.f); \ ++ } else { \ ++ switch (cnt) { \ ++ default: \ ++ /* The default case should never happen. */ \ ++ case 4: \ ++ velm.i = (unsigned)vval.vintarg[ind]; \ ++ break; \ ++ case 8: \ ++ velm.i = (unsigned short)vval.vshortarg[ind]; \ ++ break; \ ++ case 16: \ ++ velm.i = (unsigned char)vval.vchararg[ind]; \ ++ break; \ ++ } \ ++ vlen = asprintf(&vstr, vfmt , ## args, velm.i); \ ++ } \ ++ ret += vlen; \ ++ PRINT(vstr, vlen); \ ++ FLUSH(); \ ++ free(vstr); \ ++} while (0) ++ ++ /* Actually print. */ ++ if (vwidth == 0) { ++ if (vprec == 0) { ++ /* First element. */ ++ VPRINT(vcnt, 0); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i); ++ } ++ } else { ++ /* First element. */ ++ VPRINT(vcnt, 0, prec); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i, prec); ++ } ++ } ++ } else { ++ if (vprec == 0) { ++ /* First element. */ ++ VPRINT(vcnt, 0, width); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i, width); ++ } ++ } else { ++ /* First element. */ ++ VPRINT(vcnt, 0, width, prec); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i, width, prec); ++ } ++ } ++ } ++#undef VPRINT ++ ++ if (vfmt != vfmt_buf) ++ free(vfmt); ++ ++ continue; ++ } ++#endif /* ALTIVEC */ + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be +@@ -1137,7 +1503,7 @@ + realsz = dprec > size ? dprec : size; + if (sign) + realsz++; +- else if (ox[1]) ++ if (ox[1]) + realsz += 2; + + prsize = width > realsz ? width : realsz; +@@ -1151,9 +1517,9 @@ + PAD(width - realsz, blanks); + + /* prefix */ +- if (sign) { ++ if (sign) + PRINT(&sign, 1); +- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */ ++ if (ox[1]) { /* ox[1] is either x, X, or \0 */ + ox[0] = '0'; + PRINT(ox, 2); + } +@@ -1400,6 +1766,11 @@ + if (flags & LONGINT) + ADDTYPE(T_WINT); + else ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDTYPE(T_INT); + break; + case 'D': +@@ -1407,6 +1778,11 @@ + /*FALLTHROUGH*/ + case 'd': + case 'i': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif + ADDSARG(); + break; + #ifdef FLOATING_POINT +@@ -1419,6 +1795,11 @@ + case 'f': + case 'g': + case 'G': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + if (flags & LONGDBL) + ADDTYPE(T_LONG_DOUBLE); + else +@@ -1447,9 +1828,19 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDUARG(); + break; + case 'p': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDTYPE(TP_VOID); + break; + case 'S': +@@ -1467,6 +1858,11 @@ + case 'u': + case 'X': + case 'x': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDUARG(); + break; + default: /* "%?" prints ?, unless ? is NUL */ +@@ -1552,6 +1948,12 @@ + (*argtable) [n].longdoublearg = va_arg (ap, long double); + break; + #endif ++#ifdef ALTIVEC ++ case T_VECTOR: ++ if (hasAltivec) ++ ap = getvec( &((*argtable) [n]), NULL, 0, ap ); ++ break; ++#endif /* ALTIVEC */ + case TP_CHAR: + (*argtable) [n].pchararg = va_arg (ap, char *); + break; diff --git a/stdio/vfscanf.c b/stdio/FreeBSD/vfscanf.c similarity index 53% rename from stdio/vfscanf.c rename to stdio/FreeBSD/vfscanf.c index 7080736..5a93211 100644 --- a/stdio/vfscanf.c +++ b/stdio/FreeBSD/vfscanf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,44 +34,58 @@ * 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.32 2003/06/28 09:03:05 das Exp $"); +#include "namespace.h" +#include +#include #include #include -#include -#if __STDC__ +#include #include -#else -#include -#endif +#include +#include +#include +#include "un-namespace.h" + +#include "collate.h" +#include "libc_private.h" #include "local.h" #define FLOATING_POINT -#include "floatio.h" +#ifdef 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; unimplemented */ +#define LONGDBL 0x02 /* L: long double */ #define SHORT 0x04 /* h: short */ -#define SUPPRESS 0x08 /* suppress assignment */ -#define POINTER 0x10 /* weird %p pointer (`fake hex') */ -#define NOSKIP 0x20 /* do not skip blanks */ -#define QUAD 0x400 +#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 numeric conversions only: - * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point; - * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. + * 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 DPTOK 0x100 /* (float) decimal point is still legal */ -#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */ - #define PFXOK 0x100 /* 0x prefix is (still) legal */ #define NZDIGITS 0x200 /* no zero digits detected */ @@ -105,57 +95,70 @@ #define CT_CHAR 0 /* %c conversion */ #define CT_CCL 1 /* %[...] conversion */ #define CT_STRING 2 /* %s conversion */ -#define CT_INT 3 /* integer, i.e., strtoq or strtouq */ -#define CT_FLOAT 4 /* floating, i.e., strtod */ +#define CT_INT 3 /* %[dioupxX] conversion */ +#define CT_FLOAT 4 /* %[efgEFG] conversion */ + +static const u_char *__sccl(char *, const u_char *); +static int parsefloat(FILE *, char *, char *); -#define u_char unsigned char -#define u_long unsigned long +int __scanfdebug = 0; + +__weak_reference(__vfscanf, vfscanf); + +/* + * __vfscanf - MT-safe version + */ +int +__vfscanf(FILE *fp, char const *fmt0, va_list ap) +{ + int ret; -static u_char *__sccl(char *, u_char *); + FLOCKFILE(fp); + ret = __svfscanf(fp, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); +} /* - * vfscanf + * __svfscanf - non-MT-safe version of __vfscanf */ int -__svfscanf(fp, fmt0, ap) - register FILE *fp; - char const *fmt0; - va_list ap; +__svfscanf(FILE *fp, const char *fmt0, va_list ap) { - register u_char *fmt = (u_char *)fmt0; - register int c; /* character from format, or conversion */ - register size_t width; /* field width, or 0 */ - register char *p; /* points into all kinds of strings */ - register int n; /* handy integer */ - register int flags; /* flags as defined above */ - register char *p0; /* saves original value of p when necessary */ + 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 nconversions; /* number of conversions */ int nread; /* number of characters consumed from fp */ - int base; /* base argument to strtoq/strtouq */ - u_quad_t (*ccfn)(); /* conversion function (strtoq/strtouq) */ + int base; /* base argument to conversion function */ char ccltab[256]; /* character class table for %[...] */ - char buf[BUF]; /* buffer for numeric conversions */ + char buf[BUF]; /* buffer for numeric and mb conversions */ + wchar_t *wcp; /* handy wide character pointer */ + wchar_t *wcp0; /* saves original value of wcp */ + mbstate_t mbs; /* multibyte conversion state */ + size_t nconv; /* length of multibyte sequence converted */ /* `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 }; + ORIENT(fp, -1); + nassigned = 0; + nconversions = 0; nread = 0; - base = 0; /* XXX just to keep gcc happy */ - ccfn = NULL; /* XXX just to keep gcc happy */ for (;;) { c = *fmt++; if (c == 0) return (nassigned); if (isspace(c)) { - for (;;) { - if (fp->_r <= 0 && __srefill(fp)) - return (nassigned); - if (!isspace(*fp->_p)) - break; + while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p)) nread++, fp->_r--, fp->_p++; - } continue; } if (c != '%') @@ -181,26 +184,34 @@ literal: case '*': flags |= SUPPRESS; goto again; + case 'j': + flags |= INTMAXT; + goto again; case 'l': - if( flags & LONG ) - flags |= QUAD; - else + if (flags & LONG) { + flags &= ~LONG; + flags |= LONGLONG; + } else flags |= LONG; goto again; case 'q': - flags |= QUAD; + flags |= LONGLONG; /* not quite */ + goto again; + case 't': + flags |= PTRDIFFT; goto again; case 'z': - if( sizeof(size_t) == sizeof(long) ) - flags |= LONG; - if( sizeof(size_t) == sizeof(quad_t) ) - flags |= QUAD; + flags |= SIZET; goto again; case 'L': flags |= LONGDBL; goto again; case 'h': - flags |= SHORT; + if (flags & SHORT) { + flags &= ~SHORT; + flags |= SHORTSHORT; + } else + flags |= SHORT; goto again; case '0': case '1': case '2': case '3': case '4': @@ -210,61 +221,47 @@ literal: /* * Conversions. - * Those marked `compat' are for 4.[123]BSD compatibility. - * - * (According to ANSI, E and X formats are supposed - * to the same as e and x. Sorry about that.) */ - case 'D': /* compat */ - flags |= LONG; - /* FALLTHROUGH */ case 'd': c = CT_INT; - ccfn = (u_quad_t (*)())strtoq; base = 10; break; case 'i': c = CT_INT; - ccfn = (u_quad_t (*)())strtoq; base = 0; break; - case 'O': /* compat */ - flags |= LONG; - /* FALLTHROUGH */ case 'o': c = CT_INT; - ccfn = strtouq; + flags |= UNSIGNED; base = 8; break; case 'u': c = CT_INT; - ccfn = strtouq; + flags |= UNSIGNED; base = 10; break; - case 'X': /* compat XXX */ - flags |= LONG; - /* FALLTHROUGH */ + case 'X': case 'x': flags |= PFXOK; /* enable 0x prefixing */ c = CT_INT; - ccfn = strtouq; + flags |= UNSIGNED; base = 16; break; #ifdef FLOATING_POINT - case 'E': /* compat XXX */ - case 'F': /* compat */ - flags |= LONG; - /* FALLTHROUGH */ - case 'e': case 'f': case 'g': + 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; @@ -275,6 +272,9 @@ literal: c = CT_CCL; break; + case 'C': + flags |= LONG; + /* FALLTHROUGH */ case 'c': flags |= NOSKIP; c = CT_CHAR; @@ -282,37 +282,41 @@ literal: case 'p': /* pointer format is like hex */ flags |= POINTER | PFXOK; - c = CT_INT; - ccfn = strtouq; + c = CT_INT; /* assumes sizeof(uintmax_t) */ + flags |= UNSIGNED; /* >= sizeof(uintptr_t) */ base = 16; break; case 'n': + nconversions++; if (flags & SUPPRESS) /* ??? */ continue; - if (flags & SHORT) + 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 & QUAD) - *va_arg(ap, quad_t *) = 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 hacks. XXX + * Disgusting backwards compatibility hack. XXX */ case '\0': /* compat */ return (EOF); - - default: /* compat */ - if (isupper(c)) - flags |= LONG; - c = CT_INT; - ccfn = (u_quad_t (*)())strtoq; - base = 10; - break; } /* @@ -349,7 +353,46 @@ literal: /* scan arbitrary characters (sets NOSKIP) */ if (width == 0) width = 1; - if (flags & SUPPRESS) { + 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--; + memset(&mbs, 0, sizeof(mbs)); + nconv = mbrtowc(wcp, buf, n, &mbs); + 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) { @@ -378,14 +421,77 @@ literal: nread += r; nassigned++; } + nconversions++; break; case CT_CCL: /* scan a (nonempty) character class (sets NOSKIP) */ if (width == 0) - width = ~0; /* `infinity' */ + width = (size_t)~0; /* `infinity' */ /* take only those things in the class */ - if (flags & SUPPRESS) { + 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--; + memset(&mbs, 0, sizeof(mbs)); + nconv = mbrtowc(wcp, buf, n, &mbs); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; + } + if (nconv == 0) + *wcp = L'\0'; + if (nconv != (size_t)-2) { + if (wctob(*wcp) != EOF && + !ccltab[wctob(*wcp)]) { + 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++; @@ -419,13 +525,65 @@ literal: nassigned++; } nread += n; + nconversions++; break; case CT_STRING: /* like CCL, but zero-length string OK, & no NOSKIP */ if (width == 0) - width = ~0; - if (flags & SUPPRESS) { + 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 (!isspace(*fp->_p) && width != 0) { + if (n == MB_CUR_MAX) { + fp->_flags |= __SERR; + goto input_failure; + } + buf[n++] = *fp->_p; + fp->_p++; + fp->_r--; + memset(&mbs, 0, sizeof(mbs)); + nconv = mbrtowc(wcp, buf, n, &mbs); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; + } + if (nconv == 0) + *wcp = L'\0'; + if (nconv != (size_t)-2) { + if (iswspace(*wcp)) { + 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(*fp->_p)) { n++, fp->_r--, fp->_p++; @@ -449,10 +607,11 @@ literal: nread += p - p0; nassigned++; } + nconversions++; continue; case CT_INT: - /* scan an integer as if by strtoq/strtouq */ + /* scan an integer as if by the conversion function */ #ifdef hardway if (width == 0 || width > sizeof(buf) - 1) width = sizeof(buf) - 1; @@ -561,131 +720,77 @@ literal: */ if (flags & NDIGITS) { if (p > buf) - (void) ungetc(*(u_char *)--p, fp); + (void) __ungetc(*(u_char *)--p, fp); goto match_failure; } c = ((u_char *)p)[-1]; if (c == 'x' || c == 'X') { --p; - (void) ungetc(c, fp); + (void) __ungetc(c, fp); } if ((flags & SUPPRESS) == 0) { - u_quad_t res; + uintmax_t res; *p = 0; - res = (*ccfn)(buf, (char **)NULL, base); + if ((flags & UNSIGNED) == 0) + res = strtoimax(buf, (char **)NULL, base); + else + res = strtoumax(buf, (char **)NULL, base); if (flags & POINTER) - *va_arg(ap, void **) = (void *)res; + *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 & QUAD) - *va_arg(ap, quad_t *) = 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; + nconversions++; break; #ifdef FLOATING_POINT case CT_FLOAT: /* scan a floating point number as if by strtod */ -#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 | DPTOK | EXPOK; - for (p = buf; width; width--) { - c = *fp->_p; - /* - * This code mimicks the integer conversion - * code, but is much simpler. - */ - switch (c) { - - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': - flags &= ~(SIGNOK | NDIGITS); - goto fok; - - case '+': case '-': - if (flags & SIGNOK) { - flags &= ~SIGNOK; - goto fok; - } - break; - case '.': - if (flags & DPTOK) { - flags &= ~(SIGNOK | DPTOK); - goto fok; - } - break; - case 'e': case 'E': - /* no exponent without some digits */ - if ((flags&(NDIGITS|EXPOK)) == EXPOK) { - flags = - (flags & ~(EXPOK|DPTOK)) | - SIGNOK | NDIGITS; - goto fok; - } - break; - } - break; - fok: - *p++ = c; - if (--fp->_r > 0) - fp->_p++; - else if (__srefill(fp)) - break; /* EOF */ - } - /* - * If no digits, might be missing exponent digits - * (just give back the exponent) or might be missing - * regular digits, but had sign and/or decimal point. - */ - if (flags & NDIGITS) { - if (flags & EXPOK) { - /* no digits at all */ - while (p > buf) - ungetc(*(u_char *)--p, fp); - goto match_failure; - } - /* just a bad exponent (e and maybe sign) */ - c = *(u_char *)--p; - if (c != 'e' && c != 'E') { - (void) ungetc(c, fp);/* sign */ - c = *(u_char *)--p; - } - (void) ungetc(c, fp); - } + if ((width = parsefloat(fp, buf, buf + width)) == 0) + goto match_failure; if ((flags & SUPPRESS) == 0) { - long double res; - - *p = 0; - res = strtod(buf,(char **) NULL); - if (flags & LONGDBL) + if (flags & LONGDBL) { + long double res = strtold(buf, &p); *va_arg(ap, long double *) = res; - else if (flags & LONG) + } else if (flags & LONG) { + double res = strtod(buf, &p); *va_arg(ap, double *) = res; - else + } else { + float res = strtof(buf, &p); *va_arg(ap, float *) = res; + } + if (__scanfdebug && p - buf != width) + abort(); nassigned++; } - nread += p - buf; + nread += width; + nconversions++; break; #endif /* FLOATING_POINT */ } } input_failure: - return (nassigned ? nassigned : -1); + return (nconversions != 0 ? nassigned : EOF); match_failure: return (nassigned); } @@ -696,12 +801,12 @@ match_failure: * closing `]'. The table has a 1 wherever characters should be * considered part of the scanset. */ -static u_char * +static const u_char * __sccl(tab, fmt) - register char *tab; - register u_char *fmt; + char *tab; + const u_char *fmt; { - register int c, n, v; + int c, n, v, i; /* first `clear' the whole table */ c = *fmt++; /* first char hat => negated scanset */ @@ -710,9 +815,10 @@ __sccl(tab, fmt) c = *fmt++; /* get new first char */ } else v = 0; /* default => reject */ - /* should probably use memset here */ - for (n = 0; n < 256; n++) - tab[n] = v; + + /* XXX: Will not work if sizeof(tab*) > sizeof(char) */ + (void) memset(tab, v, 256); + if (c == 0) return (fmt - 1);/* format ended before closing ] */ @@ -753,15 +859,29 @@ doswitch: * we just stored in the table (c). */ n = *fmt; - if (n == ']' || n < c) { + if (n == ']' + || (__collate_load_error ? n < c : + __collate_range_cmp (n, c) < 0 + ) + ) { c = '-'; break; /* resume the for(;;) */ } fmt++; - do { /* fill in the range */ - tab[++c] = v; - } while (c < n); + /* fill in the range */ + if (__collate_load_error) { + do { + tab[++c] = v; + } while (c < n); + } else { + for (i = 0; i < 256; i ++) + if ( __collate_range_cmp (c, i) < 0 + && __collate_range_cmp (i, n) <= 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'. @@ -787,3 +907,156 @@ doswitch: } /* NOTREACHED */ } + +#ifdef FLOATING_POINT +static int +parsefloat(FILE *fp, char *buf, char *end) +{ + 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 + } state = S_START; + unsigned char c; + char decpt = *localeconv()->decimal_point; + _Bool gotmantdig = 0, ishex = 0; + + /* + * 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 = buf - 1; + for (p = buf; p < end; ) { + 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(c) && 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(c) || isdigit(c)) + 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 && isxdigit(c) || isdigit(c)) { + 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(c)) + commit = p; + else + goto parsedone; + break; + default: + abort(); + } + *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'; + return (commit - buf); +} +#endif diff --git a/stdio/FreeBSD/vfwprintf.c b/stdio/FreeBSD/vfwprintf.c new file mode 100644 index 0000000..395bc63 --- /dev/null +++ b/stdio/FreeBSD/vfwprintf.c @@ -0,0 +1,1607 @@ +/*- + * 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 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +__FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.58 2003/04/14 11:24:53 das Exp"); +#endif +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.12 2003/04/19 23:53:19 das Exp $"); + +/* + * 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 "un-namespace.h" + +#include "libc_private.h" +#include "local.h" +#include "fvwrite.h" + +/* Define FLOATING_POINT to get floating point. */ +#define FLOATING_POINT + +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; +#ifdef FLOATING_POINT + double doublearg; + long double longdoublearg; +#endif + wint_t wintarg; + wchar_t *pwchararg; +}; + +/* + * 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, + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR +}; + +static int __sbprintf(FILE *, const wchar_t *, va_list); +static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const wchar_t *, int, + char, const char *); +static wchar_t *__ultoa(u_long, wchar_t *, int, int, const wchar_t *, int, + char, const char *); +static wchar_t *__mbsconv(char *, int); +static void __find_arguments(const wchar_t *, va_list, union arg **); +static void __grow_type_table(int, enum typeid **, int *); + +/* + * 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, 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, fmt, ap); + if (ret >= 0 && __fflush(&fake)) + ret = WEOF; + 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 wchar_t * +__ultoa(u_long val, wchar_t *endp, int base, int octzero, const wchar_t *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 wchar_t *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) +{ + wchar_t *convbuf, *wcp; + const char *p; + size_t insize, nchars, nconv; + mbstate_t mbs; + + 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. + */ + memset(&mbs, 0, sizeof(mbs)); + p = mbsarg; + insize = nchars = 0; + while (nchars != (size_t)prec) { + nconv = mbrlen(p, MB_CUR_MAX, &mbs); + 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; + memset(&mbs, 0, sizeof(mbs)); + while (insize != 0) { + nconv = mbrtowc(wcp, p, insize, &mbs); + 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 + */ +int +vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) + +{ + int ret; + + FLOCKFILE(fp); + ret = __vfwprintf(fp, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); +} + +#ifdef 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 /* 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 */ + +/* + * Non-MT-safe version + */ +int +__vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) +{ + wchar_t *fmt; /* format string */ + wchar_t ch; /* character from fmt */ + int n, n2, n3; /* handy integer (short term usage) */ + 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 */ +#ifdef 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 */ + wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ + char *dtoaresult; /* buffer allocated by dtoa */ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ +#endif + u_long ulval; /* integer arguments %[diouxX] */ + uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ + 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 wchar_t *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 wchar_t xdigs_lower[16] = L"0123456789abcdef"; + static const wchar_t xdigs_upper[16] = L"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++) \ + __fputwc((ptr)[n3], fp); \ +} while (0) +#define PAD(howmany, with) do { \ + if ((n = (howmany)) > 0) { \ + while (n > PADSIZE) { \ + PRINT(with, PADSIZE); \ + n -= PADSIZE; \ + } \ + PRINT(with, n); \ + } \ +} 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(size_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; +#ifdef FLOATING_POINT + decimal_point = localeconv()->decimal_point; +#endif + convbuf = NULL; + /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ + if (cantwrite(fp)) + return (EOF); + + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + return (__sbprintf(fp, fmt0, ap)); + + 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; + fmt++; /* skip over '%' */ + + flags = 0; + dprec = 0; + width = 0; + prec = -1; + sign = '\0'; + ox[1] = '\0'; + +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; + 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()->thousands_sep); + grouping = localeconv()->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; +#ifdef 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) + *(cp = buf) = (wchar_t)GETARG(wint_t); + else + *(cp = buf) = (wchar_t)btowc(GETARG(int)); + size = 1; + sign = '\0'; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + 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; +#ifdef FLOATING_POINT +#ifdef HEXFLOAT + case 'a': + case 'A': + if (ch == 'a') { + ox[1] = 'x'; + xdigs = xdigs_lower; + expchar = 'p'; + } else { + ox[1] = 'X'; + xdigs = xdigs_upper; + expchar = 'P'; + } + /* + * XXX We don't actually have a conversion + * XXX routine for this yet. + */ + if (flags & LONGDBL) { + fparg.ldbl = (double)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); + } + if (convbuf != NULL) + free(convbuf); + cp = convbuf = __mbsconv(dtoaresult, -1); + freedtoa(dtoaresult); + goto fp_begin; +#endif + case 'e': + case 'E': + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; + else + prec++; + goto fp_begin; + case 'f': + case 'F': + expchar = '\0'; + goto fp_begin; + case 'g': + case 'G': + expchar = ch - ('g' - 'e'); + if (prec == 0) + prec = 1; +fp_begin: + if (prec < 0) + prec = DEFPREC; + if (convbuf != NULL) + free(convbuf); + 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; + } + ndig = dtoaend - dtoaresult; + cp = convbuf = __mbsconv(dtoaresult, -1); + freedtoa(dtoaresult); + 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 /* 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': + 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 + */ + 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); + 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': + 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: + 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 + */ + 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) + 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; + 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; + } + + /* + * 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++; + else 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); + } else 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 */ +#ifdef 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) { + buf[0] = *decimal_point; + PRINT(buf, 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: + 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) : 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; + memset (typetable, T_UNUSED, STATIC_ARG_TBL_SIZE); + + /* + * 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; +#ifdef FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + if (flags & SHORTINT) { + flags &= ~SHORTINT; + flags |= CHARINT; + } else + flags |= SHORTINT; + goto rflag; + case 'j': + flags |= INTMAXT; + goto rflag; + case 'l': + if (flags & LONGINT) { + flags &= ~LONGINT; + flags |= LLONGINT; + } else + flags |= LONGINT; + goto rflag; + case 'q': + flags |= LLONGINT; /* not necessarily */ + goto rflag; + case 't': + flags |= PTRDIFFT; + goto rflag; + case 'z': + flags |= SIZET; + goto rflag; + case 'C': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'c': + if (flags & LONGINT) + ADDTYPE(T_WINT); + else + ADDTYPE(T_INT); + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + ADDSARG(); + break; +#ifdef FLOATING_POINT +#ifdef HEXFLOAT + case 'a': + case 'A': +#endif + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (flags & LONGDBL) + ADDTYPE(T_LONG_DOUBLE); + else + ADDTYPE(T_DOUBLE); + break; +#endif /* FLOATING_POINT */ + case 'n': + if (flags & INTMAXT) + ADDTYPE(TP_INTMAXT); + else if (flags & PTRDIFFT) + ADDTYPE(TP_PTRDIFFT); + else if (flags & SIZET) + ADDTYPE(TP_SIZET); + else if (flags & LLONGINT) + ADDTYPE(TP_LLONG); + else if (flags & LONGINT) + ADDTYPE(TP_LONG); + else if (flags & SHORTINT) + ADDTYPE(TP_SHORT); + else if (flags & CHARINT) + ADDTYPE(TP_SCHAR); + else + ADDTYPE(TP_INT); + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': + ADDUARG(); + break; + case 'p': + ADDTYPE(TP_VOID); + break; + case 'S': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 's': + if (flags & LONGINT) + ADDTYPE(TP_WCHAR); + else + ADDTYPE(TP_CHAR); + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + case 'X': + case 'x': + ADDUARG(); + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + break; + } + } +done: + /* + * Build the argument table. + */ + if (tablemax >= STATIC_ARG_TBL_SIZE) { + *argtable = (union arg *) + malloc (sizeof (union arg) * (tablemax + 1)); + } + + (*argtable) [0].intarg = 0; + for (n = 1; n <= tablemax; n++) { + switch (typetable [n]) { + case T_UNUSED: /* whoops! */ + (*argtable) [n].intarg = va_arg (ap, int); + break; + case TP_SCHAR: + (*argtable) [n].pschararg = va_arg (ap, signed char *); + break; + case TP_SHORT: + (*argtable) [n].pshortarg = va_arg (ap, short *); + break; + case T_INT: + (*argtable) [n].intarg = va_arg (ap, int); + break; + case T_U_INT: + (*argtable) [n].uintarg = va_arg (ap, unsigned int); + break; + case TP_INT: + (*argtable) [n].pintarg = va_arg (ap, int *); + break; + case T_LONG: + (*argtable) [n].longarg = va_arg (ap, long); + break; + case T_U_LONG: + (*argtable) [n].ulongarg = va_arg (ap, unsigned long); + break; + case TP_LONG: + (*argtable) [n].plongarg = va_arg (ap, long *); + break; + case T_LLONG: + (*argtable) [n].longlongarg = va_arg (ap, long long); + break; + case T_U_LLONG: + (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); + break; + case TP_LLONG: + (*argtable) [n].plonglongarg = va_arg (ap, long long *); + break; + case T_PTRDIFFT: + (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); + break; + case TP_PTRDIFFT: + (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); + break; + case T_SIZET: + (*argtable) [n].sizearg = va_arg (ap, size_t); + break; + case TP_SIZET: + (*argtable) [n].psizearg = va_arg (ap, ssize_t *); + break; + case T_INTMAXT: + (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); + break; + case T_UINTMAXT: + (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); + break; + case TP_INTMAXT: + (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); + break; +#ifdef FLOATING_POINT + case T_DOUBLE: + (*argtable) [n].doublearg = va_arg (ap, double); + break; + case T_LONG_DOUBLE: + (*argtable) [n].longdoublearg = va_arg (ap, long double); + break; +#endif + case TP_CHAR: + (*argtable) [n].pchararg = va_arg (ap, char *); + break; + case TP_VOID: + (*argtable) [n].pvoidarg = va_arg (ap, void *); + break; + case T_WINT: + (*argtable) [n].wintarg = va_arg (ap, wint_t); + break; + case TP_WCHAR: + (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); + break; + } + } + + if ((typetable != NULL) && (typetable != stattypetable)) + free (typetable); +} + +/* + * Increase the size of the type table. + */ +static void +__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) +{ + enum typeid *const oldtable = *typetable; + const int oldsize = *tablesize; + enum typeid *newtable; + int newsize = oldsize * 2; + + if (newsize < nextarg + 1) + newsize = nextarg + 1; + if (oldsize == STATIC_ARG_TBL_SIZE) { + if ((newtable = malloc(newsize)) == NULL) + abort(); /* XXX handle better */ + bcopy(oldtable, newtable, oldsize); + } else { + if ((newtable = reallocf(oldtable, newsize)) == NULL) + abort(); /* XXX handle better */ + } + memset(&newtable[oldsize], T_UNUSED, newsize - oldsize); + + *typetable = newtable; + *tablesize = newsize; +} + + +#ifdef 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 /* FLOATING_POINT */ diff --git a/stdio/FreeBSD/vfwprintf.c.patch b/stdio/FreeBSD/vfwprintf.c.patch new file mode 100644 index 0000000..e6e2aa8 --- /dev/null +++ b/stdio/FreeBSD/vfwprintf.c.patch @@ -0,0 +1,732 @@ +--- vfwprintf.c.orig Thu Jul 24 12:42:14 2003 ++++ vfwprintf.c Sun Aug 24 16:22:23 2003 +@@ -70,9 +70,20 @@ + #include "local.h" + #include "fvwrite.h" + ++#ifdef ALTIVEC ++#include ++ ++#define VECTORTYPE vector unsigned char ++#endif /* ALTIVEC */ ++ + /* Define FLOATING_POINT to get floating point. */ + #define FLOATING_POINT + ++/* if no floating point, turn off HEXFLOAT as well */ ++#if defined(HEXFLOAT) && !defined(FLOATING_POINT) ++#undef HEXFLOAT ++#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */ ++ + union arg { + int intarg; + u_int uintarg; +@@ -92,7 +103,7 @@ + long *plongarg; + long long *plonglongarg; + ptrdiff_t *pptrdiffarg; +- size_t *psizearg; ++ ssize_t *psizearg; + intmax_t *pintmaxarg; + #ifdef FLOATING_POINT + double doublearg; +@@ -100,6 +111,16 @@ + #endif + wint_t wintarg; + wchar_t *pwchararg; ++#ifdef ALTIVEC ++ 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]; ++#endif /* ALTIVEC */ + }; + + /* +@@ -110,7 +131,11 @@ + 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 ALTIVEC ++ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR ++#else /* ! ALTIVEC */ + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR ++#endif /* ALTIVEC */ + }; + + static int __sbprintf(FILE *, const wchar_t *, va_list); +@@ -122,6 +147,37 @@ + static void __find_arguments(const wchar_t *, va_list, union arg **); + static void __grow_type_table(int, enum typeid **, int *); + ++ /* ++ * 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))) ++ ++#ifdef ALTIVEC ++#define hasAltivec (_cpu_capabilities & kHasAltivec) ++/*----------------------------------------------------------------------- ++ * getvec() must be a real subroutine. If it is a #define, then __vfprintf() ++ * would have its calling sequence changed by Altivec so that a non-Altivec ++ * processor would crash on illegal instruction. By isolating the calling ++ * sequence in getvec(), __vprintf() is callable by a non-Altivec processor. ++ *-----------------------------------------------------------------------*/ ++static va_list ++getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap) ++{ ++ dst->vectorarg = GETARG(VECTORTYPE); ++ return ap; ++} ++ ++#define SETVEC(dst) \ ++{ \ ++ ap = getvec(&dst, argtable, nextarg, ap); \ ++ nextarg++; \ ++} ++#endif /* ALTIVEC */ ++ + /* + * Helper function for `fprintf to unbuffered unix file': creates a + * temporary buffer. We only work on write-only files; this avoids +@@ -418,6 +474,15 @@ + + #endif /* FLOATING_POINT */ + ++#ifdef HEXFLOAT ++extern int __hdtoa(double d, const char *xdigs, int prec, char *cp, ++ int *expt, int *signflag, char **dtoaend); ++#if !__TYPE_LONGDOUBLE_IS_DOUBLE ++extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp, ++ int *expt, int *signflag, char **dtoaend); ++#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */ ++#endif /* HEXFLOAT */ ++ + /* + * The size of the buffer we use as scratch space for integer + * conversions, among other things. Technically, we would need the +@@ -446,6 +511,9 @@ + #define PTRDIFFT 0x800 /* ptrdiff_t */ + #define INTMAXT 0x1000 /* intmax_t */ + #define CHARINT 0x2000 /* print char using int format */ ++#ifdef ALTIVEC ++#define VECTOR 0x4000 /* Altivec vector */ ++#endif /* ALTIVEC */ + + /* + * Non-MT-safe version +@@ -496,6 +564,11 @@ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ + #endif ++#ifdef ALTIVEC ++ 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 */ +@@ -525,6 +598,15 @@ + + static const wchar_t xdigs_lower[16] = L"0123456789abcdef"; + static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF"; ++#ifdef HEXFLOAT ++#define HEXFLOATDELTA 32 ++#define HEXFLOATSTART 32 ++ static char *hexfloat = NULL; ++ static int hexfloatlen = 0; ++ const char *xdigs0; /* digits for [aA] conversion */ ++ static const char xdigs_lower0[16] = "0123456789abcdef"; ++ static const char xdigs_upper0[16] = "0123456789ABCDEF"; ++#endif /* HEXFLOAT */ + + /* + * BEWARE, these `goto error' on error, PRINT uses `n2' and +@@ -553,15 +635,6 @@ + } 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. + */ +@@ -612,7 +685,6 @@ + val = GETARG (int); \ + } + +- + thousands_sep = '\0'; + grouping = NULL; + #ifdef FLOATING_POINT +@@ -650,6 +722,9 @@ + } + if (ch == '\0') + goto done; ++#ifdef ALTIVEC ++ pct = fmt; ++#endif /* ALTIVEC */ + fmt++; /* skip over '%' */ + + flags = 0; +@@ -658,6 +733,9 @@ + prec = -1; + sign = '\0'; + ox[1] = '\0'; ++#ifdef ALTIVEC ++ vsep = 'X'; /* Illegal value, changed to defaults later. */ ++#endif /* ALTIVEC */ + + rflag: ch = *fmt++; + reswitch: switch (ch) { +@@ -673,6 +751,11 @@ + case '#': + flags |= ALT; + goto rflag; ++#ifdef ALTIVEC ++ case ',': case ';': case ':': case '_': ++ vsep = ch; ++ goto rflag; ++#endif /* ALTIVEC */ + case '*': + /*- + * ``A negative field width argument is taken as a +@@ -770,8 +853,18 @@ + case 'c': + if (flags & LONGINT) + *(cp = buf) = (wchar_t)GETARG(wint_t); ++#ifdef ALTIVEC ++ else { ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } ++ *(cp = buf) = (wchar_t)btowc(GETARG(int)); ++ } ++#else /* ALTIVEC */ + else + *(cp = buf) = (wchar_t)btowc(GETARG(int)); ++#endif /* ALTIVEC */ + size = 1; + sign = '\0'; + break; +@@ -780,6 +873,12 @@ + /*FALLTHROUGH*/ + case 'd': + case 'i': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) { + ujval = SJARG(); + if ((intmax_t)ujval < 0) { +@@ -799,38 +898,74 @@ + #ifdef HEXFLOAT + case 'a': + case 'A': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + if (ch == 'a') { + ox[1] = 'x'; +- xdigs = xdigs_lower; ++ xdigs0 = xdigs_lower0; + expchar = 'p'; + } else { + ox[1] = 'X'; +- xdigs = xdigs_upper; ++ xdigs0 = xdigs_upper0; + expchar = 'P'; + } +- /* +- * XXX We don't actually have a conversion +- * XXX routine for this yet. +- */ ++ if (!hexfloat) { ++ hexfloat = malloc(hexfloatlen = HEXFLOATSTART); ++ if (!hexfloat) ++ goto error; ++ } ++ /* one extra for integer part and another for null */ ++ if (prec > hexfloatlen - 2) { ++ int hlen = prec + HEXFLOATDELTA; ++ char *hf = realloc(hexfloat, hlen); ++ if (hf == NULL) ++ goto error; ++ hexfloat = hf; ++ hexfloatlen = hlen; ++ } + if (flags & LONGDBL) { +- fparg.ldbl = (double)GETARG(long double); +- dtoaresult = +- __hldtoa(fparg.ldbl, xdigs, prec, +- &expt, &signflag, &dtoaend); ++#if __TYPE_LONGDOUBLE_IS_DOUBLE ++ fparg.dbl = (double)GETARG(long double); ++ prec = __hdtoa(fparg.dbl, xdigs0, prec, ++ hexfloat, &expt, &signflag, &dtoaend); ++#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ ++ fparg.ldbl = GETARG(long double); ++ prec = __hldtoa(fparg.ldbl, xdigs0, prec, ++ hexfloat, &expt, &signflag, &dtoaend); ++#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ + } else { + fparg.dbl = GETARG(double); +- dtoaresult = +- __hdtoa(fparg.dbl, xdigs, prec, +- &expt, &signflag, &dtoaend); ++ prec = __hdtoa(fparg.dbl, xdigs0, prec, ++ hexfloat, &expt, &signflag, &dtoaend); ++ } ++ prec++; ++ if (expt == INT_MAX) { ++ ox[1] = 0; ++ hexfloat[1] = 0; ++ } else { ++ expt++; ++ *dtoaend = 0; ++ ndig = dtoaend - hexfloat; + } + if (convbuf != NULL) + free(convbuf); +- cp = convbuf = __mbsconv(dtoaresult, -1); +- freedtoa(dtoaresult); +- goto fp_begin; ++ cp = convbuf = __mbsconv(hexfloat, -1); ++ goto hex_begin; + #endif + case 'e': + case 'E': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; +@@ -839,10 +974,24 @@ + goto fp_begin; + case 'f': + case 'F': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + expchar = '\0'; + goto fp_begin; + case 'g': + case 'G': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ flags |= FPT; ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + expchar = ch - ('g' - 'e'); + if (prec == 0) + prec = 1; +@@ -851,6 +1000,17 @@ + prec = DEFPREC; + if (convbuf != NULL) + free(convbuf); ++#if __TYPE_LONGDOUBLE_IS_DOUBLE ++ if (flags & LONGDBL) ++ fparg.ldbl = GETARG(long double); ++ else ++ fparg.dbl = GETARG(double); ++ dtoaresult = ++ dtoa(fparg.dbl, expchar ? 2 : 3, prec, ++ &expt, &signflag, &dtoaend); ++ if (expt == 9999) ++ expt = INT_MAX; ++#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = +@@ -864,9 +1024,13 @@ + if (expt == 9999) + expt = INT_MAX; + } ++#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ + ndig = dtoaend - dtoaresult; + cp = convbuf = __mbsconv(dtoaresult, -1); + freedtoa(dtoaresult); ++#ifdef HEXFLOAT ++hex_begin: ++#endif /* HEXFLOAT */ + if (signflag) + sign = '-'; + if (expt == INT_MAX) { /* inf or nan */ +@@ -959,6 +1123,12 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else +@@ -973,6 +1143,12 @@ + * defined manner.'' + * -- ANSI X3J11 + */ ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } ++#endif /* ALTIVEC */ + ujval = (uintmax_t)(uintptr_t)GETARG(void *); + base = 16; + xdigs = xdigs_lower; +@@ -1025,6 +1201,12 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else +@@ -1037,6 +1219,12 @@ + case 'x': + xdigs = xdigs_lower; + hex: ++#ifdef ALTIVEC ++ if (flags & VECTOR) { ++ SETVEC(vval); ++ break; ++ } else ++#endif /* ALTIVEC */ + if (flags & INTMAX_SIZE) + ujval = UJARG(); + else +@@ -1081,6 +1269,14 @@ + if (size > BUF) /* should never happen */ + abort(); + break; ++#ifdef ALTIVEC ++ case 'v': ++ if (hasAltivec) { ++ flags |= VECTOR; ++ goto rflag; ++ } ++ /* drop through */ ++#endif /* ALTIVEC */ + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; +@@ -1092,6 +1288,185 @@ + break; + } + ++#ifdef ALTIVEC ++ 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. */ ++ char vfmt_buf[32]; /* Static buffer for format spec. */ ++ int vwidth = 0; /* Width specified via '*'. */ ++ int vprec = 0; /* Precision specified via '*'. */ ++ union { /* Element. */ ++ int i; ++ float f; ++ } velm; ++ char *vstr; /* Used for asprintf(). */ ++ int vlen; /* Length returned by asprintf(). */ ++ ++ /* ++ * Set vfmt. If vfmt_buf may not be big enough, ++ * malloc() space, taking care to free it later. ++ */ ++ if (&fmt[-1] - pct < sizeof(vfmt_buf)) ++ vfmt = vfmt_buf; ++ else ++ vfmt = (char *)malloc(&fmt[-1] - pct + 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) { ++ vfmt[j++] = 'h'; ++ vcnt = 8; ++ } else if (flags & LONGINT) { ++ vfmt[j++] = 'l'; ++ vcnt = 4; ++ } else { ++ switch (ch) { ++ case 'a': ++ case 'A': ++ case 'e': ++ case 'E': ++ case 'f': ++ case 'g': ++ case 'G': ++ vcnt = 4; ++ break; ++ default: ++ /* ++ * The default case should never ++ * happen. ++ */ ++ case 'c': ++ case 'd': ++ case 'i': ++ case 'u': ++ case 'o': ++ case 'p': ++ case 'x': ++ case 'X': ++ vcnt = 16; ++ } ++ } ++ vfmt[j++] = ch; ++ vfmt[j++] = '\0'; ++ ++/* Get a vector element. */ ++#define VPRINT(cnt, ind, args...) do { \ ++ if (flags & FPT) { \ ++ velm.f = vval.vfloatarg[ind]; \ ++ vlen = asprintf(&vstr, vfmt , ## args, velm.f); \ ++ } else { \ ++ switch (cnt) { \ ++ default: \ ++ /* The default case should never happen. */ \ ++ case 4: \ ++ velm.i = (unsigned)vval.vintarg[ind]; \ ++ break; \ ++ case 8: \ ++ velm.i = (unsigned short)vval.vshortarg[ind]; \ ++ break; \ ++ case 16: \ ++ velm.i = (unsigned char)vval.vchararg[ind]; \ ++ break; \ ++ } \ ++ vlen = asprintf(&vstr, vfmt , ## args, velm.i); \ ++ } \ ++ ret += vlen; \ ++ PRINT(vstr, vlen); \ ++ free(vstr); \ ++} while (0) ++ ++ /* Actually print. */ ++ if (vwidth == 0) { ++ if (vprec == 0) { ++ /* First element. */ ++ VPRINT(vcnt, 0); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i); ++ } ++ } else { ++ /* First element. */ ++ VPRINT(vcnt, 0, prec); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i, prec); ++ } ++ } ++ } else { ++ if (vprec == 0) { ++ /* First element. */ ++ VPRINT(vcnt, 0, width); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i, width); ++ } ++ } else { ++ /* First element. */ ++ VPRINT(vcnt, 0, width, prec); ++ for (i = 1; i < vcnt; i++) { ++ /* Separator. */ ++ if (vsep) ++ PRINT(&vsep, 1); ++ ++ /* Element. */ ++ VPRINT(vcnt, i, width, prec); ++ } ++ } ++ } ++#undef VPRINT ++ ++ if (vfmt != vfmt_buf) ++ free(vfmt); ++ ++ continue; ++ } ++#endif /* ALTIVEC */ + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be +@@ -1109,7 +1484,7 @@ + realsz = dprec > size ? dprec : size; + if (sign) + realsz++; +- else if (ox[1]) ++ if (ox[1]) + realsz += 2; + + prsize = width > realsz ? width : realsz; +@@ -1123,9 +1498,9 @@ + PAD(width - realsz, blanks); + + /* prefix */ +- if (sign) { ++ if (sign) + PRINT(&sign, 1); +- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */ ++ if (ox[1]) { /* ox[1] is either x, X, or \0 */ + ox[0] = '0'; + PRINT(ox, 2); + } +@@ -1368,6 +1743,11 @@ + if (flags & LONGINT) + ADDTYPE(T_WINT); + else ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDTYPE(T_INT); + break; + case 'D': +@@ -1387,6 +1767,11 @@ + case 'f': + case 'g': + case 'G': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + if (flags & LONGDBL) + ADDTYPE(T_LONG_DOUBLE); + else +@@ -1415,9 +1800,19 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDUARG(); + break; + case 'p': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDTYPE(TP_VOID); + break; + case 'S': +@@ -1435,6 +1830,11 @@ + case 'u': + case 'X': + case 'x': ++#ifdef ALTIVEC ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* ALTIVEC */ + ADDUARG(); + break; + default: /* "%?" prints ?, unless ? is NUL */ +@@ -1520,6 +1920,12 @@ + (*argtable) [n].longdoublearg = va_arg (ap, long double); + break; + #endif ++#ifdef ALTIVEC ++ case T_VECTOR: ++ if (hasAltivec) ++ ap = getvec( &((*argtable) [n]), NULL, 0, ap ); ++ break; ++#endif /* ALTIVEC */ + case TP_CHAR: + (*argtable) [n].pchararg = va_arg (ap, char *); + break; diff --git a/stdio/FreeBSD/vfwscanf.c b/stdio/FreeBSD/vfwscanf.c new file mode 100644 index 0000000..f452c8e --- /dev/null +++ b/stdio/FreeBSD/vfwscanf.c @@ -0,0 +1,873 @@ +/*- + * 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 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +__FBSDID("FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.32 2003/06/28 09:03:05 das Exp "); +#endif +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.6 2003/07/05 03:39:23 tjr Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" +#include "local.h" + +#define FLOATING_POINT + +#ifdef 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 */ + +/* + * 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 int parsefloat(FILE *, wchar_t *, wchar_t *); + +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, fmt, ap); + FUNLOCKFILE(fp); + return (ret); +} + +/* + * Non-MT-safe version. + */ +int +__vfwscanf(FILE * __restrict fp, 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 nconversions; /* number of conversions */ + 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 */ + mbstate_t mbs; /* multibyte state */ + char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */ + + /* `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; + nconversions = 0; + nread = 0; + ccls = ccle = NULL; + for (;;) { + c = *fmt++; + if (c == 0) + return (nassigned); + if (iswspace(c)) { + while ((c = __fgetwc(fp)) != WEOF && + iswspace(c)) + ; + if (c != WEOF) + __ungetwc(c, fp); + 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)) == WEOF) + goto input_failure; + if (wi != c) { + __ungetwc(wi, fp); + goto input_failure; + } + nread++; + continue; + + 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; + +#ifdef 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': + nconversions++; + 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)) != WEOF && iswspace(wi)) + nread++; + if (wi == WEOF) + goto input_failure; + __ungetwc(wi, fp); + } + + /* + * 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)) != 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; + memset(&mbs, 0, sizeof(mbs)); + while (width != 0 && + (wi = __fgetwc(fp)) != WEOF) { + if (width >= MB_CUR_MAX && + !(flags & SUPPRESS)) { + nconv = wcrtomb(mbp, wi, &mbs); + if (nconv == (size_t)-1) + goto input_failure; + } else { + nconv = wcrtomb(mbbuf, wi, + &mbs); + if (nconv == (size_t)-1) + goto input_failure; + if (nconv > width) { + __ungetwc(wi, fp); + 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++; + } + nconversions++; + 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)) != WEOF && + width-- != 0 && INCCL(wi)) + n++; + if (wi != WEOF) + __ungetwc(wi, fp); + if (n == 0) + goto match_failure; + } else if (flags & LONG) { + p0 = p = va_arg(ap, wchar_t *); + while ((wi = __fgetwc(fp)) != WEOF && + width-- != 0 && INCCL(wi)) + *p++ = (wchar_t)wi; + if (wi != WEOF) + __ungetwc(wi, fp); + n = p - p0; + if (n == 0) + goto match_failure; + *p = 0; + nassigned++; + } else { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + n = 0; + memset(&mbs, 0, sizeof(mbs)); + while ((wi = __fgetwc(fp)) != WEOF && + width != 0 && INCCL(wi)) { + if (width >= MB_CUR_MAX && + !(flags & SUPPRESS)) { + nconv = wcrtomb(mbp, wi, &mbs); + if (nconv == (size_t)-1) + goto input_failure; + } else { + nconv = wcrtomb(mbbuf, wi, + &mbs); + 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); + if (!(flags & SUPPRESS)) { + *mbp = 0; + nassigned++; + } + } + nread += n; + nconversions++; + 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)) != WEOF && + width-- != 0 && + !iswspace(wi)) + nread++; + if (wi != WEOF) + __ungetwc(wi, fp); + } else if (flags & LONG) { + p0 = p = va_arg(ap, wchar_t *); + while ((wi = __fgetwc(fp)) != WEOF && + width-- != 0 && + !iswspace(wi)) { + *p++ = (wchar_t)wi; + nread++; + } + if (wi != WEOF) + __ungetwc(wi, fp); + *p = '\0'; + nassigned++; + } else { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + memset(&mbs, 0, sizeof(mbs)); + while ((wi = __fgetwc(fp)) != WEOF && + width != 0 && + !iswspace(wi)) { + if (width >= MB_CUR_MAX && + !(flags & SUPPRESS)) { + nconv = wcrtomb(mbp, wi, &mbs); + if (nconv == (size_t)-1) + goto input_failure; + } else { + nconv = wcrtomb(mbbuf, wi, + &mbs); + 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); + if (!(flags & SUPPRESS)) { + *mbp = 0; + nassigned++; + } + } + nconversions++; + 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); + /* + * 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; + goto ok; + } + break; + + /* x ok iff flag still set & 2nd char */ + case 'x': case 'X': + if (flags & PFXOK && p == buf + 1) { + 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); + 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); + goto match_failure; + } + c = p[-1]; + if (c == 'x' || c == 'X') { + --p; + __ungetwc(c, fp); + } + if ((flags & SUPPRESS) == 0) { + uintmax_t res; + + *p = 0; + if ((flags & UNSIGNED) == 0) + res = wcstoimax(buf, NULL, base); + else + res = wcstoumax(buf, NULL, base); + 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; + nconversions++; + break; + +#ifdef FLOATING_POINT + case CT_FLOAT: + /* scan a floating point number as if by strtod */ + if (width == 0 || width > sizeof(buf) / + sizeof(*buf) - 1) + width = sizeof(buf) / sizeof(*buf) - 1; + if ((width = parsefloat(fp, buf, buf + width)) == 0) + goto match_failure; + if ((flags & SUPPRESS) == 0) { + if (flags & LONGDBL) { + long double res = wcstold(buf, &p); + *va_arg(ap, long double *) = res; + } else if (flags & LONG) { + double res = wcstod(buf, &p); + *va_arg(ap, double *) = res; + } else { + float res = wcstof(buf, &p); + *va_arg(ap, float *) = res; + } + if (__scanfdebug && p - buf != width) + abort(); + nassigned++; + } + nread += width; + nconversions++; + break; +#endif /* FLOATING_POINT */ + } + } +input_failure: + return (nconversions != 0 ? nassigned : EOF); +match_failure: + return (nassigned); +} + +#ifdef FLOATING_POINT +static int +parsefloat(FILE *fp, wchar_t *buf, wchar_t *end) +{ + 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; + wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point; + _Bool gotmantdig = 0, ishex = 0; + + /* + * 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 = buf - 1; + c = WEOF; + for (p = buf; p < end; ) { + if ((c = __fgetwc(fp)) == 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(c) && 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(c) || iswdigit(c)) + 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(c) || iswdigit(c)) { + 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(c)) + commit = p; + else + goto parsedone; + break; + default: + abort(); + } + *p++ = c; + c = WEOF; + } + +parsedone: + if (c != WEOF) + __ungetwc(c, fp); + while (commit < --p) + __ungetwc(*p, fp); + *++commit = '\0'; + return (commit - buf); +} +#endif diff --git a/stdio/vprintf.c b/stdio/FreeBSD/vprintf.c similarity index 64% rename from stdio/vprintf.c rename to stdio/FreeBSD/vprintf.c index 894c73e..329bbf0 100644 --- a/stdio/vprintf.c +++ b/stdio/FreeBSD/vprintf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,17 @@ * 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 int -vprintf(fmt, ap) - char const *fmt; - _BSD_VA_LIST_ ap; +vprintf(const char * __restrict fmt, __va_list ap) { + return (vfprintf(stdout, fmt, ap)); } diff --git a/stdio/vscanf.c b/stdio/FreeBSD/vscanf.c similarity index 63% rename from stdio/vscanf.c rename to stdio/FreeBSD/vscanf.c index 15c7085..6945736 100644 --- a/stdio/vscanf.c +++ b/stdio/FreeBSD/vscanf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,14 +34,27 @@ * 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 "namespace.h" #include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" int vscanf(fmt, ap) - const char *fmt; - _BSD_VA_LIST_ ap; + const char * __restrict fmt; + __va_list ap; { + int retval; - return (__svfscanf(stdin, fmt, ap)); + FLOCKFILE(stdin); + retval = __svfscanf(stdin, fmt, ap); + FUNLOCKFILE(stdin); + return (retval); } diff --git a/stdio/FreeBSD/vsnprintf.c b/stdio/FreeBSD/vsnprintf.c new file mode 100644 index 0000000..3a43939 --- /dev/null +++ b/stdio/FreeBSD/vsnprintf.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[] = "@(#)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 +#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, fmt, ap); + if (on > 0) + *f._p = '\0'; + return (ret); +} diff --git a/stdio/vsprintf.c b/stdio/FreeBSD/vsprintf.c similarity index 64% rename from stdio/vsprintf.c rename to stdio/FreeBSD/vsprintf.c index 8ec19c6..698f752 100644 --- a/stdio/vsprintf.c +++ b/stdio/FreeBSD/vsprintf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,23 +34,30 @@ * 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 #include +#include "local.h" int -vsprintf(str, fmt, ap) - char *str; - const char *fmt; - _BSD_VA_LIST_ ap; +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; - ret = vfprintf(&f, fmt, ap); + f._extra = &ext; + INITEXTRA(&f); + ret = __vfprintf(&f, fmt, ap); *f._p = 0; return (ret); } diff --git a/stdio/vsscanf.c b/stdio/FreeBSD/vsscanf.c similarity index 67% rename from stdio/vsscanf.c rename to stdio/FreeBSD/vsscanf.c index 1e4a208..e7bbe25 100644 --- a/stdio/vsscanf.c +++ b/stdio/FreeBSD/vsscanf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,9 +34,18 @@ * 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 #include +#include "local.h" + +static int +eofread(void *, char *, int); /* ARGSUSED */ static int @@ -75,17 +60,21 @@ eofread(cookie, buf, len) int vsscanf(str, fmt, ap) - const char *str; - const char *fmt; - _BSD_VA_LIST_ 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(&f, fmt, ap)); } diff --git a/stdio/FreeBSD/vswprintf.c b/stdio/FreeBSD/vswprintf.c new file mode 100644 index 0000000..fdea252 --- /dev/null +++ b/stdio/FreeBSD/vswprintf.c @@ -0,0 +1,94 @@ +/* $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.3 2003/01/07 06:20:47 tjr Exp $"); + +#include +#include +#include +#include +#include "local.h" + +int +vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, + __va_list ap) +{ + FILE f; + struct __sFILEX ext; + mbstate_t mbs; + char *mbp; + int ret, sverrno; + + 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, fmt, ap); + if (ret < 0) { + sverrno = errno; + free(f._bf._base); + errno = sverrno; + return (-1); + } + *f._p = '\0'; + mbp = f._bf._base; + memset(&mbs, 0, sizeof(mbs)); + /* + * XXX Undo the conversion from wide characters to multibyte that + * fputwc() did in __vfwprintf(). + */ + if (mbsrtowcs(s, (const char **)&mbp, n, &mbs) == (size_t)-1) { + free(f._bf._base); + errno = EILSEQ; + return (-1); + } + free(f._bf._base); + if (s[n - 1] != L'\0') { + s[n - 1] = L'\0'; + errno = EOVERFLOW; + return (-1); + } + + return (ret); +} diff --git a/stdio/FreeBSD/vswscanf.c b/stdio/FreeBSD/vswscanf.c new file mode 100644 index 0000000..89ca3b0 --- /dev/null +++ b/stdio/FreeBSD/vswscanf.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 + * 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.1 2002/09/23 12:40:06 tjr Exp $"); + +#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) +{ + FILE f; + mbstate_t mbs; + struct __sFILEX ext; + char *mbstr; + size_t mlen; + int r; + + /* + * XXX Convert the wide character string to multibyte, which + * __vfwscanf() will convert back to wide characters. + */ + if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX + 1)) == NULL) + return (EOF); + memset(&mbs, 0, sizeof(mbs)); + if ((mlen = wcsrtombs(mbstr, &str, SIZE_T_MAX, &mbs)) == (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, fmt, ap); + free(mbstr); + + return (r); +} diff --git a/stdio/FreeBSD/vwprintf.c b/stdio/FreeBSD/vwprintf.c new file mode 100644 index 0000000..4390c06 --- /dev/null +++ b/stdio/FreeBSD/vwprintf.c @@ -0,0 +1,39 @@ +/*- + * 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 +#include +#include + +int +vwprintf(const wchar_t * __restrict fmt, va_list ap) +{ + + return (vfwprintf(stdout, fmt, ap)); +} diff --git a/stdio/FreeBSD/vwscanf.c b/stdio/FreeBSD/vwscanf.c new file mode 100644 index 0000000..6e103d5 --- /dev/null +++ b/stdio/FreeBSD/vwscanf.c @@ -0,0 +1,39 @@ +/*- + * 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 +#include +#include + +int +vwscanf(const wchar_t * __restrict fmt, va_list ap) +{ + + return (vfwscanf(stdin, fmt, ap)); +} diff --git a/stdio/wbuf.c b/stdio/FreeBSD/wbuf.c similarity index 73% rename from stdio/wbuf.c rename to stdio/FreeBSD/wbuf.c index c34932a..000c469 100644 --- a/stdio/wbuf.c +++ b/stdio/FreeBSD/wbuf.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,6 +34,11 @@ * 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.10 2002/08/13 09:30:41 tjr Exp $"); #include #include "local.h" @@ -66,13 +47,15 @@ * 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) - register int c; - register FILE *fp; + int c; + FILE *fp; { - register int n; + int n; /* * In case we cannot write, or longjmp takes us out early, @@ -86,6 +69,8 @@ __swbuf(c, fp) 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 @@ -97,14 +82,14 @@ __swbuf(c, fp) */ n = fp->_p - fp->_bf._base; if (n >= fp->_bf._size) { - if (fflush(fp)) + 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)) + if (__fflush(fp)) return (EOF); return (c); } diff --git a/stdio/printf.3 b/stdio/FreeBSD/wprintf.3 similarity index 57% rename from stdio/printf.3 rename to stdio/FreeBSD/wprintf.3 index dacf1d4..def25bd 100644 --- a/stdio/printf.3 +++ b/stdio/FreeBSD/wprintf.3 @@ -34,70 +34,58 @@ .\" SUCH DAMAGE. .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.17.2.10 2001/12/14 18:33:57 ru Exp $ +.\" 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 June 4, 1993 -.Dt PRINTF 3 +.Dd July 5, 2003 +.Dt WPRINTF 3 .Os .Sh NAME -.Nm printf , fprintf , sprintf , snprintf , asprintf , -.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf -.Nd formatted output conversion +.Nm wprintf , fwprintf , swprintf , +.Nm vwprintf , vfwprintf , vswprintf +.Nd formatted wide character output conversion .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdio.h +.In wchar.h .Ft int -.Fn printf "const char *format" ... +.Fn fwprintf "FILE * restrict stream" "const wchar_t * restrict format" ... .Ft int -.Fn fprintf "FILE *stream" "const char *format" ... +.Fn swprintf "wchar_t * restrict ws" "size_t n" "const wchar_t * restrict format" ... .Ft int -.Fn sprintf "char *str" "const char *format" ... -.Ft int -.Fn snprintf "char *str" "size_t size" "const char *format" ... -.Ft int -.Fn asprintf "char **ret" "const char *format" ... +.Fn wprintf "const wchar_t * restrict format" ... .In stdarg.h .Ft int -.Fn vprintf "const char *format" "va_list ap" -.Ft int -.Fn vfprintf "FILE *stream" "const char *format" "va_list ap" -.Ft int -.Fn vsprintf "char *str" "const char *format" "va_list ap" +.Fn vfwprintf "FILE * restrict stream" "const wchar_t * restrict" "va_list ap" .Ft int -.Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap" +.Fn vswprintf "wchar_t * restrict ws" "size_t n" "const wchar_t *restrict format" "va_list ap" .Ft int -.Fn vasprintf "char **ret" "const char *format" "va_list ap" +.Fn vwprintf "const wchar_t * restrict format" "va_list ap" .Sh DESCRIPTION The -.Fn printf +.Fn wprintf family of functions produces output according to a .Fa format as described below. -.Fn Printf +The +.Fn wprintf and -.Fn vprintf +.Fn vwprintf +functions write output to -.Pa stdout , +.Dv stdout , the standard output stream; -.Fn fprintf +.Fn fwprintf and -.Fn vfprintf +.Fn vfwprintf write output to the given output .Fa stream ; -.Fn sprintf , -.Fn snprintf , -.Fn vsprintf , -and -.Fn vsnprintf -write to the character string -.Fa str ; +.Fn swprintf and -.Fn asprintf -and -.Fn vasprintf -dynamically allocate a new string with -.Xr malloc 3 . +.Fn vswprintf +write to the wide character string +.Fa ws . .Pp These functions write the output under the control of a .Fa format @@ -109,60 +97,18 @@ are converted for output. These functions return the number of characters printed (not including the trailing .Ql \e0 -used to end output to strings), -except for -.Fn snprintf -and -.Fn vsnprintf , -which return the number of characters that would have been printed if the -.Fa size -were unlimited -(again, not including the final -.Ql \e0 ) . -.Pp -.Fn Asprintf -and -.Fn vasprintf -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 -.Fn Snprintf -and -.Fn vsnprintf -will write at most -.Fa size Ns \-1 -of the characters printed into the output string -(the -.Fa size Ns 'th -character then gets the terminating -.Ql \e0 ) ; -if the return value is greater than or equal to the -.Fa size -argument, the string was too short -and some of the printed characters were discarded. +used to end output to strings). .Pp -.Fn Sprintf +The +.Fn swprintf and -.Fn vsprintf -effectively assume an infinite -.Fa size . +.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 -.\" multibyte characters (not .Cm % ) , which are copied unchanged to the output stream; @@ -190,12 +136,9 @@ 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 -hyphen -.It -A -.Cm # -character -specifying that the value should be converted to an +.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 , @@ -219,7 +162,7 @@ for .Cm X conversions) prepended to it. For -.Cm e , E , f , g , +.Cm a , A , e , E , f , F , g , and .Cm G conversions, the result will always contain a decimal point, even if no @@ -231,11 +174,8 @@ and .Cm G conversions, trailing zeros are not removed from the result as they would otherwise be. -.It -A -.Cm 0 -(zero) -character specifying zero padding. +.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. @@ -246,10 +186,9 @@ and the .Cm 0 flag is ignored. -.It -A negative field width flag -.Cm \- -indicates the converted value is to be left adjusted on the field boundary. +.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, @@ -259,20 +198,30 @@ A overrides a .Cm 0 if both are given. -.It -A space, specifying that a blank should be left before a positive number +.It So "\ " Sc (space) +A blank should be left before a positive number produced by a signed conversion -.Cm ( d , e , E , f , g , G , +.Cm ( a , A , d , e , E , f , F , g , G , or .Cm i ) . -.It -A -.Cm + -character specifying that a sign always be placed before a +.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. @@ -291,9 +240,9 @@ This gives the minimum number of digits to appear for and .Cm X conversions, the number of digits to appear after the decimal-point for -.Cm e , E , +.Cm a , A , e , E , f , and -.Cm f +.Cm F conversions, the maximum number of significant digits for .Cm g and @@ -303,79 +252,68 @@ string for .Cm s conversions. .It -The optional character -.Cm h , -specifying that a following -.Cm d , i , o , u , x , +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 corresponds to a -.Vt short int -or -.Vt unsigned short int -argument, or that a following -.Cm n -conversion corresponds to a pointer to a -.Vt short int -argument. -.It -The optional character -.Cm l -(ell) specifying that a following -.Cm d , i , o , u , x , -or -.Cm X -conversion applies to a pointer to a -.Vt long int -or -.Vt unsigned long int -argument, or that a following -.Cm n -conversion corresponds to a pointer to a -.Vt long int -argument. -.It -The optional characters -.Cm ll -(ell ell) specifying that a following -.Cm d , i , o , u , x , -or -.Cm X -conversion applies to a pointer to a -.Vt long long int -or -.Vt unsigned long long int -argument, or that a following -.Cm n -conversion corresponds to a pointer to a -.Vt long long int -argument. -.It -The optional character -.Cm q , -specifying that a following -.Cm d , i , o , u , 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 corresponds to a -.Vt quad int +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 -.Vt unsigned quad int -argument, or that a following +.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 corresponds to a pointer to a -.Vt quad int -argument. -.It -The character -.Cm L -specifying that a following -.Cm e , E , f , g , +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 corresponds to a -.Vt long double -argument. +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 @@ -393,11 +331,12 @@ 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 (nn$) +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 "diouxX" +.Bl -tag -width ".Cm diouxX" .It Cm diouxX The .Vt int @@ -415,11 +354,11 @@ and .Cm X ) notation. The letters -.Cm abcdef +.Dq Li abcdef are used for .Cm x conversions; the letters -.Cm ABCDEF +.Dq Li ABCDEF are used for .Cm X conversions. @@ -428,7 +367,7 @@ appear; if the converted value requires fewer digits, it is padded on the left with zeros. .It Cm DOU The -.Vt long int +.Vt "long int" argument is converted to signed decimal, unsigned octal, or unsigned decimal, as if the format had been .Cm ld , lo , @@ -440,7 +379,9 @@ These conversion characters are deprecated, and will eventually disappear. The .Vt double argument is rounded and converted in the style -.Oo \- Oc Ns d Ns Cm \&. Ns ddd Ns Cm e Ns \\*[Pm]dd +.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; @@ -450,17 +391,38 @@ zero, no decimal-point character appears. An .Cm E conversion uses the letter -.Cm E +.Ql E (rather than -.Cm e ) +.Ql e ) to introduce the exponent. The exponent always contains at least two digits; if the value is zero, the exponent is 00. -.It Cm f +.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 -.Oo \- Oc Ns ddd Ns Cm \&. Ns ddd , +.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 @@ -474,6 +436,8 @@ argument is converted in style or .Cm e (or +.Cm F +or .Cm E for .Cm G @@ -483,22 +447,89 @@ 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 +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 , +.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 * +.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) +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; @@ -509,9 +540,30 @@ 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 * +.Vt "void *" pointer argument is printed in hexadecimal (as if by .Ql %#x or @@ -519,7 +571,7 @@ or .It Cm n The number of characters written so far is stored into the integer indicated by the -.Vt int * +.Vt "int *" (or variant) pointer argument. No argument is converted. .It Cm % @@ -532,112 +584,39 @@ 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 field; if the result of a conversion is wider than the field width, the +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 +Refer to +.Xr printf 3 . .Sh SEE ALSO -.Xr printf 1 , -.Xr scanf 3 +.Xr btowc 3 , +.Xr fputws 3 , +.Xr printf 3 , +.Xr putwc 3 , +.Xr setlocale 3 , +.Xr wcsrtombs 3 , +.Xr wscanf 3 .Sh STANDARDS -The -.Fn fprintf , -.Fn printf , -.Fn sprintf , -.Fn vprintf , -.Fn vfprintf , +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 vsprintf +.Fn vswprintf functions conform to -.St -isoC . -.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 -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. -Unfortunately, this interface is not portable. +.St -isoC-99 . diff --git a/stdio/FreeBSD/wprintf.3.patch b/stdio/FreeBSD/wprintf.3.patch new file mode 100644 index 0000000..b243b57 --- /dev/null +++ b/stdio/FreeBSD/wprintf.3.patch @@ -0,0 +1,52 @@ +--- wprintf.3.orig Thu Aug 21 18:19:12 2003 ++++ wprintf.3 Thu Aug 21 18:16:28 2003 +@@ -224,6 +224,20 @@ + .Xr localeconv 3 . + .El + .It ++An optional seperator character ( ++.Cm \ , | \; | \ : | _ ++) used for seperating 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 +328,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 diff --git a/stdio/FreeBSD/wprintf.c b/stdio/FreeBSD/wprintf.c new file mode 100644 index 0000000..4b5596e --- /dev/null +++ b/stdio/FreeBSD/wprintf.c @@ -0,0 +1,45 @@ +/*- + * 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 +#include +#include + +int +wprintf(const wchar_t * __restrict fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfwprintf(stdout, fmt, ap); + va_end(ap); + + return (ret); +} diff --git a/stdio/FreeBSD/wscanf.3 b/stdio/FreeBSD/wscanf.3 new file mode 100644 index 0000000..b7eac3c --- /dev/null +++ b/stdio/FreeBSD/wscanf.3 @@ -0,0 +1,483 @@ +.\" 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 wscanf , +.Nm fwscanf , +.Nm swscanf , +.Nm vwscanf , +.Nm vswscanf , +.Nm vfwscanf +.Nd wide character input format conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft int +.Fn wscanf "const wchar_t * restrict format" ... +.Ft int +.Fn fwscanf "FILE * restrict stream" "const wchar_t * restrict format" ... +.Ft int +.Fn swscanf "const wchar_t * restrict str" "const wchar_t * restrict format" ... +.In stdarg.h +.Ft int +.Fn vwscanf "const wchar_t * restrict format" "va_list ap" +.Ft int +.Fn vswscanf "const wchar_t * restrict str" "const wchar_t * restrict format" "va_list ap" +.Ft int +.Fn vfwscanf "FILE * restrict stream" "const wchar_t * restrict format" "va_list ap" +.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 str . +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. +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). +.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 +.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/FreeBSD/wscanf.c b/stdio/FreeBSD/wscanf.c new file mode 100644 index 0000000..8629027 --- /dev/null +++ b/stdio/FreeBSD/wscanf.c @@ -0,0 +1,45 @@ +/*- + * 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 +#include +#include + +int +wscanf(const wchar_t * __restrict fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = vfwscanf(stdin, fmt, ap); + va_end(ap); + + return (r); +} diff --git a/stdio/wsetup.c b/stdio/FreeBSD/wsetup.c similarity index 73% rename from stdio/wsetup.c rename to stdio/FreeBSD/wsetup.c index 991c180..67c9e2f 100644 --- a/stdio/wsetup.c +++ b/stdio/FreeBSD/wsetup.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,6 +34,11 @@ * 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.8 2002/03/22 21:53:04 obrien Exp $"); #include #include @@ -70,7 +51,7 @@ */ int __swsetup(fp) - register FILE *fp; + FILE *fp; { /* make sure stdio is set up */ if (!__sdidinit) diff --git a/stdio/Makefile.inc b/stdio/Makefile.inc index 0054af3..d2e4300 100644 --- a/stdio/Makefile.inc +++ b/stdio/Makefile.inc @@ -1,47 +1,69 @@ # @(#)Makefile.inc 8.3 (Berkeley) 4/17/94 -# $FreeBSD: src/lib/libc/stdio/Makefile.inc,v 1.20 2001/03/27 17:26:52 ru Exp $ +# $FreeBSD: src/lib/libc/stdio/Makefile.inc,v 1.32 2003/01/10 06:22:28 tjr Exp $ # stdio sources .PATH: ${.CURDIR}/stdio -SRCS+= clrerr.c findfp.c fsetpos.c mktemp.c scanf.c ungetc.c \ - fclose.c flags.c ftell.c perror.c setbuf.c vfprintf.c \ - fdopen.c fopen.c funopen.c printf.c setbuffer.c vfscanf.c \ - feof.c fprintf.c fvwrite.c putc.c setvbuf.c vprintf.c \ - ferror.c fpurge.c fwalk.c putchar.c snprintf.c vscanf.c \ - fflush.c fputc.c fwrite.c puts.c sprintf.c vsnprintf.c \ - fgetc.c fputs.c getc.c putw.c sscanf.c vsprintf.c \ - fgetln.c fread.c getchar.c refill.c stdio.c vsscanf.c \ - fgetpos.c freopen.c gets.c remove.c tempnam.c wbuf.c \ - fgets.c fscanf.c getw.c rewind.c tmpfile.c wsetup.c \ - fileno.c fseek.c makebuf.c rget.c tmpnam.c asprintf.c \ - vasprintf.c +CFLAGS+= -DHEXFLOAT +SRCS += hexfloat.c + +.include "Makefile.fbsd_begin" +FBSDSRCS= _flock_stub.c asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c \ + fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c fgetws.c \ + fileno.c findfp.c flags.c fopen.c fprintf.c fpurge.c fputc.c fputs.c \ + fputwc.c fputws.c fread.c freopen.c fscanf.c fseek.c fsetpos.c \ + ftell.c funopen.c fvwrite.c fwalk.c fwide.c fwprintf.c fwscanf.c \ + fwrite.c getc.c getchar.c gets.c getw.c getwc.c getwchar.c makebuf.c \ + mktemp.c perror.c printf.c putc.c putchar.c puts.c putw.c putwc.c \ + putwchar.c refill.c remove.c rewind.c rget.c scanf.c setbuf.c \ + setbuffer.c setvbuf.c snprintf.c sprintf.c sscanf.c stdio.c \ + swprintf.c swscanf.c tempnam.c tmpfile.c tmpnam.c ungetc.c ungetwc.c \ + unlocked.c vasprintf.c vfprintf.c vfscanf.c vfwprintf.c vfwscanf.c \ + vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c vswprintf.c \ + vswscanf.c vwprintf.c vwscanf.c wbuf.c wprintf.c wscanf.c wsetup.c +FBSDORIGHDRS= floatio.h fvwrite.h glue.h local.h +.include "Makefile.fbsd_end" .if ${LIB} == "c" -MAN3+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fopen.3 fputs.3 \ - fread.3 fseek.3 funopen.3 getc.3 mktemp.3 printf.3 putc.3 remove.3 \ - scanf.3 setbuf.3 stdio.3 tmpnam.3 ungetc.3 +.include "Makefile.fbsd_begin" +FBSDMAN3= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetws.3 flockfile.3 \ + fopen.3 fputs.3 fputws.3 fread.3 fseek.3 funopen.3 fwide.3 getc.3 \ + getwc.3 mktemp.3 printf.3 putc.3 putwc.3 remove.3 scanf.3 setbuf.3 \ + stdio.3 tmpnam.3 ungetc.3 ungetwc.3 wprintf.3 wscanf.3 +.include "Makefile.fbsd_end" -MLINKS+=ferror.3 clearerr.3 ferror.3 feof.3 ferror.3 fileno.3 +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+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3 MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 MLINKS+=fputs.3 puts.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 getchar.3 getc.3 getw.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+=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+=putc.3 fputc.3 putc.3 putchar.3 putc.3 putw.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+=scanf.3 fscanf.3 scanf.3 sscanf.3 scanf.3 vfscanf.3 scanf.3 vscanf.3 \ scanf.3 vsscanf.3 MLINKS+=setbuf.3 setbuffer.3 setbuf.3 setlinebuf.3 setbuf.3 setvbuf.3 MLINKS+=tmpnam.3 tempnam.3 tmpnam.3 tmpfile.3 +MLINKS+=wprintf.3 fwprintf.3 wprintf.3 swprintf.3 \ + wprintf.3 vwprintf.3 wprintf.3 vfwprintf.3 wprintf.3 vswprintf.3 +MLINKS+=wscanf.3 fwscanf.3 wscanf.3 swscanf.3 wscanf.3 vwscanf.3 \ + wscanf.3 vswscanf.3 wscanf.3 vfwscanf.3 .endif diff --git a/stdio/feof.c b/stdio/feof.c deleted file mode 100644 index 87c3812..0000000 --- a/stdio/feof.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -/* - * A subroutine version of the macro feof. - */ -#undef feof - -int -feof(fp) - FILE *fp; -{ - return (__sfeof(fp)); -} diff --git a/stdio/ferror.c b/stdio/ferror.c deleted file mode 100644 index 25ab013..0000000 --- a/stdio/ferror.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -/* - * A subroutine version of the macro ferror. - */ -#undef ferror - -int -ferror(fp) - FILE *fp; -{ - return (__sferror(fp)); -} diff --git a/stdio/fgetpos.c b/stdio/fgetpos.c deleted file mode 100644 index 81b0f66..0000000 --- a/stdio/fgetpos.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -int -fgetpos(fp, pos) - FILE *fp; - fpos_t *pos; -{ - int retval; - /* FLOCKFILE(fp); */ - retval = (*pos = ftello(fp)) == (fpos_t)-1; - /* FUNLOCKFILE(fp); */ - return(retval); -} diff --git a/stdio/fileno.c b/stdio/fileno.c deleted file mode 100644 index c3f44e2..0000000 --- a/stdio/fileno.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -/* - * A subroutine version of the macro fileno. - */ -#undef fileno - -int -fileno(fp) - FILE *fp; -{ - return (__sfileno(fp)); -} diff --git a/stdio/floatio.h b/stdio/floatio.h deleted file mode 100644 index 6e777db..0000000 --- a/stdio/floatio.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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. - */ - -/* - * Floating point scanf/printf (input/output) definitions. - */ - -/* 11-bit exponent (VAX G floating point) is 308 decimal digits */ -#define MAXEXP 308 -/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */ -#define MAXFRACT 39 diff --git a/stdio/fprintf.c b/stdio/fprintf.c deleted file mode 100644 index a499a7d..0000000 --- a/stdio/fprintf.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 __STDC__ -#include -#else -#include -#endif - -int -#if __STDC__ -fprintf(FILE *fp, const char *fmt, ...) -#else -fprintf(fp, fmt, va_alist) - FILE *fp; - char *fmt; - va_dcl -#endif -{ - int ret; - va_list ap; - -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = vfprintf(fp, fmt, ap); - va_end(ap); - return (ret); -} diff --git a/stdio/fpurge.c b/stdio/fpurge.c deleted file mode 100644 index a9360c1..0000000 --- a/stdio/fpurge.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 -#include -#include -#include "local.h" - -/* - * fpurge: like fflush, but without writing anything: leave the - * given FILE's buffer empty. - */ -int -fpurge(fp) - register FILE *fp; -{ - if (!fp->_flags) { - errno = EBADF; - return(EOF); - } - - if (HASUB(fp)) - FREEUB(fp); - fp->_p = fp->_bf._base; - fp->_r = 0; - fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; - return (0); -} diff --git a/stdio/fscanf.c b/stdio/fscanf.c deleted file mode 100644 index 8ef75a5..0000000 --- a/stdio/fscanf.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 __STDC__ -#include -#else -#include -#endif - -int -#if __STDC__ -fscanf(FILE *fp, char const *fmt, ...) { - int ret; - va_list ap; - - va_start(ap, fmt); -#else -fscanf(fp, fmt, va_alist) - FILE *fp; - char *fmt; - va_dcl -{ - int ret; - va_list ap; - - va_start(ap); -#endif - ret = __svfscanf(fp, fmt, ap); - va_end(ap); - return (ret); -} diff --git a/stdio/fwalk.c b/stdio/fwalk.c deleted file mode 100644 index 7f0305e..0000000 --- a/stdio/fwalk.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 -#include -#include "local.h" -#include "glue.h" - -int -_fwalk(function) - register int (*function)(); -{ - register FILE *fp; - register int n, ret; - register struct glue *g; - - ret = 0; - for (g = &__sglue; g != NULL; g = g->next) - for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) - if (fp->_flags != 0) - ret |= (*function)(fp); - return (ret); -} diff --git a/stdio/getc.c b/stdio/getc.c deleted file mode 100644 index 49724a8..0000000 --- a/stdio/getc.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -/* - * A subroutine version of the macro getc. - */ -#undef getc - -int -getc(fp) - register FILE *fp; -{ - return (__sgetc(fp)); -} diff --git a/stdio/gets.c b/stdio/gets.c deleted file mode 100644 index 696f632..0000000 --- a/stdio/gets.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 -#include - -char * -gets(buf) - char *buf; -{ - register int c; - register char *s; - static int warned; - static char w[] = - "warning: this program uses gets(), which is unsafe.\r\n"; - - if (!warned) { - (void) write(STDERR_FILENO, w, sizeof(w) - 1); - warned = 1; - } - for (s = buf; (c = getchar()) != '\n';) - if (c == EOF) - if (s == buf) - return (NULL); - else - break; - else - *s++ = c; - *s = 0; - return (buf); -} diff --git a/stdio/hexfloat.c b/stdio/hexfloat.c new file mode 100644 index 0000000..2e59d9e --- /dev/null +++ b/stdio/hexfloat.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifdef HEXFLOAT + +/* + * hexfloat.c provides routines that vfprintf and vfwprintf can call to convert + * floating point numbers to hexidecimal, as used by the %a and %A conversions. + * This is necessarily dependent not only on the floating point data format, + * but also byte order and existence of long double type. + * + * The union hexdouble represents the IEEE-754 double precision format, while + * union hexlongdouble represents the IEEE-754 extended double precision + * format. + */ + +#include +#include +#include + +#define EXPBIAS 1023 +#define EXPMIN -1022 +#define EXPSPECIAL 2047 +#define FRACTHEX 13 + +union hexdouble { + double d; + struct { +#if defined(__ppc__) + unsigned int sign:1; + unsigned int exp:11; + unsigned long long fract:52; +#elif defined(__i386__) + unsigned long long fract:52; + unsigned int exp:11; + unsigned int sign:1; +#else +#error Unsupported architecture +#endif + } s; +}; + +#if !__TYPE_LONGDOUBLE_IS_DOUBLE +#ifdef __i386__ + +#define LEXPBIAS 16383 +#define LEXPMIN -16382 +#define LEXPSPECIAL 32767 +#define LFRACTHEX 16 + +union hexlongdouble { + long double d; + struct { + unsigned long long fract:63; + unsigned int i:1; + unsigned int exp:15; + unsigned int sign:1; + } s; +}; +#endif /* __i386__ */ +#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */ + +int +__hdtoa(double d, const char *xdigs, int prec, char *cp, + int *expt, int *signflag, char **dtoaend) +{ + union hexdouble u; + char buf[FRACTHEX]; + char *hp; + int i; + long long fract; + //char *start = cp; //DEBUG + + u.d = d; + //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG + *signflag = u.s.sign; + fract = u.s.fract; + switch (u.s.exp) { + case EXPSPECIAL: /* NaN or Inf */ + *expt = INT_MAX; + *cp = (fract ? 'N' : 'I'); + return 0; + case 0: /* Zero or denormalized */ + *cp++ = '0'; + *expt = (fract ? EXPMIN : 0); + break; + default: /* Normal numbers */ + *cp++ = '1'; + *expt = u.s.exp - EXPBIAS; + break; + } + if (prec < 0) + prec = FRACTHEX; + //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG + if (prec > 0) { + int dig = (prec > FRACTHEX ? FRACTHEX : prec); + int zero = prec - dig; + int shift = FRACTHEX - dig; + if (shift > 0) + fract >>= (shift << 2); + for (hp = buf + dig, i = dig; i > 0; i--) { + *--hp = xdigs[fract & 0xf]; + fract >>= 4; + } + strncpy(cp, hp, dig); + cp += dig; + while(zero-- > 0) + *cp++ = '0'; + } + *dtoaend = cp; + //while (start < cp) putchar(*start++); //DEBUG + //putchar('\n'); //DEBUG + return prec; +} + +#if !__TYPE_LONGDOUBLE_IS_DOUBLE +#ifdef __i386__ +int +__hldtoa(long double d, const char *xdigs, int prec, char *cp, + int *expt, int *signflag, char **dtoaend) +{ + union hexlongdouble u; + char buf[LFRACTHEX]; + char *hp; + int i; + unsigned long long fract; + //char *start = cp; //DEBUG + + u.d = d; + //printf("d=%Lg u.d=%Lg\n", d, u.d); //DEBUG + //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG + *signflag = u.s.sign; + fract = (u.s.fract << 1); + switch (u.s.exp) { + case LEXPSPECIAL: /* NaN or Inf */ + *expt = INT_MAX; + *cp = (fract ? 'N' : 'I'); + return 0; + default: /* Normal or denormalized */ + *cp++ = u.s.i ? '1' : '0'; + *expt = u.s.exp - LEXPBIAS; + break; + } + if (prec < 0) + prec = LFRACTHEX; + //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG + if (prec > 0) { + int dig = (prec > LFRACTHEX ? LFRACTHEX : prec); + int zero = prec - dig; + int shift = LFRACTHEX - dig; + if (shift > 0) + fract >>= (shift << 2); + for (hp = buf + dig, i = dig; i > 0; i--) { + *--hp = xdigs[fract & 0xf]; + fract >>= 4; + } + strncpy(cp, hp, dig); + cp += dig; + while(zero-- > 0) + *cp++ = '0'; + } + *dtoaend = cp; + //while (start < cp) putchar(*start++); //DEBUG + //putchar('\n'); //DEBUG + return prec; +} +#endif /* __i386__ */ +#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */ + +#endif /* HEXFLOAT */ diff --git a/stdio/printf.c b/stdio/printf.c deleted file mode 100644 index 85a1903..0000000 --- a/stdio/printf.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 __STDC__ -#include -#else -#include -#endif - -int -#if __STDC__ -printf(char const *fmt, ...) -#else -printf(fmt, va_alist) - char *fmt; - va_dcl -#endif -{ - int ret; - va_list ap; - -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = vfprintf(stdout, fmt, ap); - va_end(ap); - return (ret); -} diff --git a/stdio/putc.c b/stdio/putc.c deleted file mode 100644 index 1e2fc37..0000000 --- a/stdio/putc.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -/* - * A subroutine version of the macro putc. - */ -#undef putc - -int -putc(c, fp) - int c; - register FILE *fp; -{ - return (__sputc(c, fp)); -} diff --git a/stdio/rewind.c b/stdio/rewind.c deleted file mode 100644 index 5b7cbca..0000000 --- a/stdio/rewind.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 -#include - -void -rewind(fp) - register FILE *fp; -{ - (void) fseek(fp, 0L, SEEK_SET); - clearerr(fp); - errno = 0; /* not required, but seems reasonable */ -} diff --git a/stdio/scanf.c b/stdio/scanf.c deleted file mode 100644 index 790c3be..0000000 --- a/stdio/scanf.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 __STDC__ -#include -#else -#include -#endif - -int -#if __STDC__ -scanf(char const *fmt, ...) -#else -scanf(fmt, va_alist) - char *fmt; - va_dcl -#endif -{ - int ret; - va_list ap; - -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = __svfscanf(stdin, fmt, ap); - va_end(ap); - return (ret); -} diff --git a/stdio/snprintf.c b/stdio/snprintf.c deleted file mode 100644 index d7218d1..0000000 --- a/stdio/snprintf.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 __STDC__ -#include -#else -#include -#endif - -int -#if __STDC__ -snprintf(char *str, size_t n, char const *fmt, ...) -#else -snprintf(str, n, fmt, va_alist) - char *str; - size_t n; - char *fmt; - va_dcl -#endif -{ - int ret; - va_list ap; - FILE f; - - if ((int)n < 1) - return (EOF); -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n - 1; - ret = vfprintf(&f, fmt, ap); - *f._p = 0; - va_end(ap); - return (ret); -} diff --git a/stdio/sprintf.c b/stdio/sprintf.c deleted file mode 100644 index 82355a0..0000000 --- a/stdio/sprintf.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 __STDC__ -#include -#else -#include -#endif -#include -#include "local.h" - -int -#if __STDC__ -sprintf(char *str, char const *fmt, ...) -#else -sprintf(str, fmt, va_alist) - char *str; - char *fmt; - va_dcl -#endif -{ - int ret; - va_list ap; - FILE f; - - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = INT_MAX; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = vfprintf(&f, fmt, ap); - va_end(ap); - *f._p = 0; - return (ret); -} diff --git a/stdio/vsnprintf.c b/stdio/vsnprintf.c deleted file mode 100644 index 5c7286c..0000000 --- a/stdio/vsnprintf.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 - -int -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - _BSD_VA_LIST_ ap; -{ - int ret; - FILE f; - - if ((int)n < 1) - return (EOF); - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n - 1; - ret = vfprintf(&f, fmt, ap); - *f._p = 0; - return (ret); -} diff --git a/stdlib/FreeBSD/_Exit_.c b/stdlib/FreeBSD/_Exit_.c new file mode 100644 index 0000000..3a2e94e --- /dev/null +++ b/stdlib/FreeBSD/_Exit_.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/abort.3 b/stdlib/FreeBSD/abort.3 similarity index 100% rename from stdlib/abort.3 rename to stdlib/FreeBSD/abort.3 diff --git a/stdlib/FreeBSD/abort.c b/stdlib/FreeBSD/abort.c new file mode 100644 index 0000000..28acb30 --- /dev/null +++ b/stdlib/FreeBSD/abort.c @@ -0,0 +1,86 @@ +/* + * 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.8 2002/07/10 16:35:02 wollman Exp $"); + +#include +#include +#include +#include +#include + +void (*__cleanup)(); + +/* XXX - why are these declarations here? */ +extern int __sys_sigprocmask(int, const sigset_t *, sigset_t *); +extern int __sys_sigaction(int, const struct sigaction *, + struct sigaction *); + +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)__sys_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)kill(getpid(), SIGABRT); + + /* + * If SIGABRT was ignored, or caught and the handler returns, do + * it again, only harder. + */ + act.sa_handler = SIG_DFL; + act.sa_flags = 0; + sigfillset(&act.sa_mask); + (void)__sys_sigaction(SIGABRT, &act, NULL); + sigdelset(&act.sa_mask, SIGABRT); + (void)__sys_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)kill(getpid(), SIGABRT); + exit(1); +} diff --git a/stdlib/FreeBSD/abort.c.patch b/stdlib/FreeBSD/abort.c.patch new file mode 100644 index 0000000..938d418 --- /dev/null +++ b/stdlib/FreeBSD/abort.c.patch @@ -0,0 +1,18 @@ +--- abort.c.orig Mon Apr 28 16:37:26 2003 ++++ abort.c Sat May 3 14:27:55 2003 +@@ -43,12 +43,9 @@ + #include + #include + +-void (*__cleanup)(); +- +-/* XXX - why are these declarations here? */ +-extern int __sys_sigprocmask(int, const sigset_t *, sigset_t *); +-extern int __sys_sigaction(int, const struct sigaction *, +- struct sigaction *); ++extern void (*__cleanup)(); ++#define __sys_sigprocmask sigprocmask ++#define __sys_sigaction sigaction + + void + abort() diff --git a/stdlib/abs.3 b/stdlib/FreeBSD/abs.3 similarity index 94% rename from stdlib/abs.3 rename to stdlib/FreeBSD/abs.3 index e1d0337..f2556e8 100644 --- a/stdlib/abs.3 +++ b/stdlib/FreeBSD/abs.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)abs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.10 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.12 2002/12/18 13:33:03 ru Exp $ .\" -.Dd June 4, 1993 +.Dd November 14, 2001 .Dt ABS 3 .Os .Sh NAME @@ -54,7 +54,7 @@ The function computes the absolute value of the integer -.Ar j . +.Fa j . .Sh RETURN VALUES The .Fn abs @@ -66,12 +66,14 @@ the absolute value. .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 . +.St -isoC-99 . .Sh BUGS The absolute value of the most negative integer remains negative. diff --git a/i386/gen/abs.c b/stdlib/FreeBSD/abs.c similarity index 63% rename from i386/gen/abs.c rename to stdlib/FreeBSD/abs.c index 97a925a..26f87eb 100644 --- a/i386/gen/abs.c +++ b/stdlib/FreeBSD/abs.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,11 +31,11 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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 @@ -69,6 +45,3 @@ abs(j) { return(j < 0 ? -j : j); } -#else -#warning ----------- Check for implementation of abs() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/stdlib/alloca.3 b/stdlib/FreeBSD/alloca.3 similarity index 100% rename from stdlib/alloca.3 rename to stdlib/FreeBSD/alloca.3 diff --git a/stdlib/FreeBSD/alloca.3.patch b/stdlib/FreeBSD/alloca.3.patch new file mode 100644 index 0000000..6853902 --- /dev/null +++ b/stdlib/FreeBSD/alloca.3.patch @@ -0,0 +1,12 @@ +--- alloca.3.orig Mon Apr 28 16:37:26 2003 ++++ alloca.3 Mon May 19 14:22:55 2003 +@@ -41,6 +41,9 @@ + .Sh LIBRARY + .Lb libc + .Sh SYNOPSIS ++.In alloca.h ++or ++.br + .In stdlib.h + .Ft void * + .Fn alloca "size_t size" diff --git a/stdlib/atexit.3 b/stdlib/FreeBSD/atexit.3 similarity index 86% rename from stdlib/atexit.3 rename to stdlib/FreeBSD/atexit.3 index f1b0acf..72a9977 100644 --- a/stdlib/atexit.3 +++ b/stdlib/FreeBSD/atexit.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)atexit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.7 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.10 2002/12/18 13:33:03 ru Exp $ .\" -.Dd June 4, 1993 +.Dd September 6, 2002 .Dt ATEXIT 3 .Os .Sh NAME @@ -53,15 +53,27 @@ The .Fn atexit function registers the given -.Ar function +.Fa function to be called at program exit, whether via .Xr exit 3 or via return from the program's -.Em main . +.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, and 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 diff --git a/stdlib/atexit.c b/stdlib/FreeBSD/atexit.c similarity index 65% rename from stdlib/atexit.c rename to stdlib/FreeBSD/atexit.c index dcc32a7..51b195b 100644 --- a/stdlib/atexit.c +++ b/stdlib/FreeBSD/atexit.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,12 +34,28 @@ * 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.6 2002/03/22 21:53:09 obrien Exp $"); +#include "namespace.h" #include #include +#include +#include #include "atexit.h" +#include "un-namespace.h" + +#include "libc_private.h" + +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 *__atexit = NULL; /* points to head of LIFO stack */ +struct atexit *__atexit; /* points to head of LIFO stack */ /* * Register a function to be performed at exit. @@ -73,17 +65,31 @@ atexit(fn) void (*fn)(); { static struct atexit __atexit0; /* one guaranteed table */ - register struct atexit *p; + struct atexit *p; + _MUTEX_LOCK(&atexit_mutex); if ((p = __atexit) == NULL) __atexit = p = &__atexit0; - else if (p->ind >= ATEXIT_SIZE) { - if ((p = malloc(sizeof(*p))) == NULL) + 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++] = fn; + _MUTEX_UNLOCK(&atexit_mutex); return (0); } diff --git a/stdlib/atexit.h b/stdlib/FreeBSD/atexit.h similarity index 64% rename from stdlib/atexit.h rename to stdlib/FreeBSD/atexit.h index 96c679e..b6aa183 100644 --- a/stdlib/atexit.h +++ b/stdlib/FreeBSD/atexit.h @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -53,6 +29,9 @@ * LIABILITY, OR TORT (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.2 2002/03/22 23:42:03 obrien Exp $ */ /* must be at least 32 to guarantee ANSI conformance */ @@ -64,5 +43,4 @@ struct atexit { void (*fns[ATEXIT_SIZE])(); /* the table itself */ }; -extern struct atexit *__atexit; /* points to head of LIFO stack */ - /* storage allocated in atexit.c */ +extern struct atexit *__atexit; /* points to head of LIFO stack */ diff --git a/stdlib/atof.3 b/stdlib/FreeBSD/atof.3 similarity index 94% rename from stdlib/atof.3 rename to stdlib/FreeBSD/atof.3 index 1f5042d..785f9d1 100644 --- a/stdlib/atof.3 +++ b/stdlib/FreeBSD/atof.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atof.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.12 2001/09/26 20:10:10 asmodai Exp $ +.\" $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 @@ -54,9 +54,9 @@ string to double The .Fn atof function converts the initial portion of the string pointed to by -.Ar nptr +.Fa nptr to -.Ar double +.Vt double representation. .Pp It is equivalent to: @@ -78,9 +78,11 @@ function has been deprecated by .Fn strtod and should not be used in new code. .Sh ERRORS -The +The function .Fn atof -function does not detect errors. +need not affect the value of +.Va errno +on an error. .Sh SEE ALSO .Xr atoi 3 , .Xr atol 3 , diff --git a/stdlib/atof.c b/stdlib/FreeBSD/atof.c similarity index 63% rename from stdlib/atof.c rename to stdlib/FreeBSD/atof.c index c80bea3..7519ce1 100644 --- a/stdlib/atof.c +++ b/stdlib/FreeBSD/atof.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -53,8 +29,15 @@ * LIABILITY, OR TORT (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/atof.c,v 1.4 2002/03/22 21:53:09 obrien Exp $ */ +#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.4 2002/03/22 21:53:09 obrien Exp $"); #include @@ -62,6 +45,5 @@ double atof(ascii) const char *ascii; { - return (strtod(ascii, NULL)); + return strtod(ascii, (char **)NULL); } - diff --git a/stdlib/atoi.3 b/stdlib/FreeBSD/atoi.3 similarity index 94% rename from stdlib/atoi.3 rename to stdlib/FreeBSD/atoi.3 index 40ac028..6f71dc1 100644 --- a/stdlib/atoi.3 +++ b/stdlib/FreeBSD/atoi.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)atoi.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.8 2001/10/01 12:44:24 ru Exp $ +.\" $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 @@ -54,9 +54,9 @@ string to integer The .Fn atoi function converts the initial portion of the string pointed to by -.Em nptr +.Fa nptr to -.Em integer +.Vt int representation. .Pp It is equivalent to: @@ -74,9 +74,11 @@ function has been deprecated by .Fn strtol and should not be used in new code. .Sh ERRORS -The +The function .Fn atoi -function does not detect errors. +need not affect the value of +.Va errno +on an error. .Sh SEE ALSO .Xr atof 3 , .Xr atol 3 , diff --git a/stdlib/atoi.c b/stdlib/FreeBSD/atoi.c similarity index 62% rename from stdlib/atoi.c rename to stdlib/FreeBSD/atoi.c index d105bc0..3da2fda 100644 --- a/stdlib/atoi.c +++ b/stdlib/FreeBSD/atoi.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,12 +31,17 @@ * 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 -#include +int atoi(str) const char *str; { - return((int)strtol(str, (char **)NULL, 10)); + return (int)strtol(str, (char **)NULL, 10); } diff --git a/stdlib/atol.3 b/stdlib/FreeBSD/atol.3 similarity index 79% rename from stdlib/atol.3 rename to stdlib/FreeBSD/atol.3 index c18ced0..bbd7ddb 100644 --- a/stdlib/atol.3 +++ b/stdlib/FreeBSD/atol.3 @@ -34,35 +34,63 @@ .\" SUCH DAMAGE. .\" .\" @(#)atol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.6 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.13 2002/01/09 14:03:54 ru Exp $ .\" -.Dd June 4, 1993 +.Dd November 28, 2001 .Dt ATOL 3 .Os .Sh NAME -.Nm atol +.Nm atol , atoll .Nd convert .Tn ASCII -string to long integer +string to +.Vt long +or +.Vt "long long" +integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .Ft long .Fn atol "const char *nptr" +.Ft "long long" +.Fn atoll "const char *nptr" .Sh DESCRIPTION The .Fn atol function converts the initial portion of the string pointed to by -.Ar nptr +.Fa nptr to -.Em long integer +.Vt long +integer representation. .Pp It is equivalent to: -.Bd -literal -offset indent -strtol(nptr, (char **)NULL, 10); -.Ed +.Pp +.Dl "strtol(nptr, (char **)NULL, 10);" +.Pp +The +.Fn atoll +function converts the initial portion of the string pointed to by +.Fa nptr +to +.Vt "long long" +integer +representation. +.Pp +It is equivalent to: +.Pp +.Dl "strtoll(nptr, (char **)NULL, 10);" +.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 , @@ -75,3 +103,8 @@ The function conforms to .St -isoC . +The +.Fn atoll +function +conforms to +.St -isoC-99 . diff --git a/stdlib/atol.c b/stdlib/FreeBSD/atol.c similarity index 62% rename from stdlib/atol.c rename to stdlib/FreeBSD/atol.c index 86f07d7..c66c04e 100644 --- a/stdlib/atol.c +++ b/stdlib/FreeBSD/atol.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,13 +31,17 @@ * 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 #include long atol(str) const char *str; { - return(strtol(str, (char **)NULL, 10)); + return strtol(str, (char **)NULL, 10); } diff --git a/stdlib/FreeBSD/atoll.c b/stdlib/FreeBSD/atoll.c new file mode 100644 index 0000000..b7c38b8 --- /dev/null +++ b/stdlib/FreeBSD/atoll.c @@ -0,0 +1,44 @@ +/* + * 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 + +long long +atoll(str) + const char *str; +{ + return strtoll(str, (char **)NULL, 10); +} diff --git a/stdlib/bsearch.3 b/stdlib/FreeBSD/bsearch.3 similarity index 100% rename from stdlib/bsearch.3 rename to stdlib/FreeBSD/bsearch.3 diff --git a/stdlib/bsearch.c b/stdlib/FreeBSD/bsearch.c similarity index 70% rename from stdlib/bsearch.c rename to stdlib/FreeBSD/bsearch.c index ffc740c..7717582 100644 --- a/stdlib/bsearch.c +++ b/stdlib/FreeBSD/bsearch.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 @@ -77,16 +58,16 @@ */ void * bsearch(key, base0, nmemb, size, compar) - register const void *key; + const void *key; const void *base0; size_t nmemb; - register size_t size; - register int (*compar) __P((const void *, const void *)); + size_t size; + int (*compar)(const void *, const void *); { - register const char *base = base0; - register size_t lim; - register int cmp; - register const void *p; + const char *base = base0; + size_t lim; + int cmp; + const void *p; for (lim = nmemb; lim != 0; lim >>= 1) { p = base + (lim >> 1) * size; diff --git a/stdlib/div.3 b/stdlib/FreeBSD/div.3 similarity index 93% rename from stdlib/div.3 rename to stdlib/FreeBSD/div.3 index b567fed..49f2b4f 100644 --- a/stdlib/div.3 +++ b/stdlib/FreeBSD/div.3 @@ -32,9 +32,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)div.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.6 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.8 2002/12/18 13:33:03 ru Exp $ .\" -.Dd June 4, 1993 +.Dd November 14, 2001 .Dt DIV 3 .Os .Sh NAME @@ -55,16 +55,18 @@ computes the value and returns the quotient and remainder in a structure named .Fa div_t that contains two -.Em int +.Vt int members named -.Fa quot +.Va quot and -.Fa rem . +.Va rem . .Sh SEE ALSO -.Xr ldiv 3 +.Xr imaxdiv 3 , +.Xr ldiv 3 , +.Xr lldiv 3 .Sh STANDARDS The .Fn div function conforms to -.St -isoC . +.St -isoC-99 . diff --git a/stdlib/div.c b/stdlib/FreeBSD/div.c similarity index 74% rename from stdlib/div.c rename to stdlib/FreeBSD/div.c index 932db84..54278d6 100644 --- a/stdlib/div.c +++ b/stdlib/FreeBSD/div.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -58,6 +34,11 @@ * 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 */ diff --git a/stdlib/exit.3 b/stdlib/FreeBSD/exit.3 similarity index 67% rename from stdlib/exit.3 rename to stdlib/FreeBSD/exit.3 index e74285e..cf50bcd 100644 --- a/stdlib/exit.3 +++ b/stdlib/FreeBSD/exit.3 @@ -34,13 +34,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)exit.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/exit.3,v 1.10 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/exit.3,v 1.13 2002/12/13 16:53:50 ru Exp $ .\" -.Dd June 4, 1993 +.Dd September 9, 2002 .Dt EXIT 3 .Os .Sh NAME -.Nm exit +.Nm exit , _Exit .Nd perform normal program termination .Sh LIBRARY .Lb libc @@ -48,12 +48,18 @@ .In stdlib.h .Ft void .Fn exit "int status" +.Ft void +.Fn _Exit "int status" .Sh DESCRIPTION -.Fn Exit -terminates a process. +The +.Fn exit +and +.Fn _Exit +functions terminate a process. .Pp -Before termination it performs the following functions in the -order listed: +Before termination, +.Fn exit +performs the following functions in the order listed: .Bl -enum -offset indent .It Call the functions registered with the @@ -69,22 +75,51 @@ Unlink all files created with the function. .El .Pp -Passing arbitrary values back to the environment as -.Ar status -is considered bad style; -you should use the values -.Dv EXIT_SUCCESS +The +.Fn _Exit +function terminates without calling the functions registered with the +.Xr atexit 3 +function, and may or may not perform the other actions listed. +Both functions make the low-order eight bits of the +.Fa status +argument available to a parent process which has called a +.Xr wait 2 Ns -family +function. +.Pp +The C Standard +.Pq St -isoC-99 +defines the values +.Li 0 , +.Dv EXIT_SUCCESS , and -.Dv EXIT_FAILURE . -If portability is not a concern, you may -use the values described in -.Xr sysexits 3 . +.Dv EXIT_FAILURE +as possible values of +.Fa status . +Cooperating processes may use other values; +in a program which might be called by a mail transfer agent, the +the values described in +.Xr sysexits 3 +may be used to provide more information to the parent process. +.Pp +Note that +.Fn exit +does nothing to prevent bottomless recursion should a function registered +using +.Xr atexit 3 +itself call +.Fn exit . +Such functions must call +.Fn _Exit +instead (although this has other effects as well which may not be desired). .Sh RETURN VALUES The .Fn exit -function -never returns. +and +.Fn _Exit +functions +never return. .Sh SEE ALSO +.Xr wait 2 , .Xr _exit 2 , .Xr atexit 3 , .Xr intro 3 , @@ -93,6 +128,7 @@ never returns. .Sh STANDARDS The .Fn exit -function -conforms to -.St -isoC . +and +.Fn _Exit +functions conform to +.St -isoC-99 . diff --git a/stdlib/exit.c b/stdlib/FreeBSD/exit.c similarity index 65% rename from stdlib/exit.c rename to stdlib/FreeBSD/exit.c index 1ccb848..6fefb36 100644 --- a/stdlib/exit.c +++ b/stdlib/FreeBSD/exit.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,12 +31,28 @@ * 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.6 2002/03/22 21:53:10 obrien Exp $"); +#include "namespace.h" #include #include +#include "un-namespace.h" #include "atexit.h" -void (*__cleanup)() = NULL; +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) + * thread-safe, but without a (significant) penalty to non-threaded + * processes. + */ +int __isthreaded = 0; /* * Exit, flushing stdio buffers if necessary. @@ -69,8 +61,13 @@ void exit(status) int status; { - register struct atexit *p; - register int n; + struct atexit *p; + int n; + + /* Ensure that the auto-initialization routine is linked in: */ + extern int _thread_autoinit_dummy_decl; + + _thread_autoinit_dummy_decl = 1; for (p = __atexit; p; p = p->next) for (n = p->ind; --n >= 0;) diff --git a/stdlib/FreeBSD/exit.c.patch b/stdlib/FreeBSD/exit.c.patch new file mode 100644 index 0000000..c7f7c9b --- /dev/null +++ b/stdlib/FreeBSD/exit.c.patch @@ -0,0 +1,30 @@ +--- exit.c.orig Mon Apr 28 16:37:26 2003 ++++ exit.c Sat May 3 14:28:31 2003 +@@ -46,15 +46,6 @@ + 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) +- * thread-safe, but without a (significant) penalty to non-threaded +- * processes. +- */ +-int __isthreaded = 0; +- +-/* + * Exit, flushing stdio buffers if necessary. + */ + void +@@ -63,11 +54,6 @@ + { + struct atexit *p; + int n; +- +- /* Ensure that the auto-initialization routine is linked in: */ +- extern int _thread_autoinit_dummy_decl; +- +- _thread_autoinit_dummy_decl = 1; + + for (p = __atexit; p; p = p->next) + for (n = p->ind; --n >= 0;) diff --git a/stdlib/getenv.3 b/stdlib/FreeBSD/getenv.3 similarity index 95% rename from stdlib/getenv.3 rename to stdlib/FreeBSD/getenv.3 index 9a2d953..32cdd8f 100644 --- a/stdlib/getenv.3 +++ b/stdlib/FreeBSD/getenv.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getenv.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/stdlib/getenv.3,v 1.12 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/getenv.3,v 1.13 2002/12/18 13:33:03 ru Exp $ .\" .Dd December 11, 1993 .Dt GETENV 3 @@ -63,9 +63,9 @@ host .Em environment list . For compatibility with differing environment conventions, the given arguments -.Ar name +.Fa name and -.Ar value +.Fa value may be appended and prepended, respectively, with an equal sign @@ -74,30 +74,31 @@ with an equal sign The .Fn getenv function obtains the current value of the environment variable, -.Ar name . +.Fa name . If the variable -.Ar name +.Fa name is not in the current environment, a null pointer is returned. .Pp The .Fn setenv function inserts or resets the environment variable -.Ar name +.Fa name in the current environment list. If the variable -.Ar name +.Fa name does not exist in the list, it is inserted with the given -.Ar value . +.Fa value . If the variable does exist, the argument -.Ar overwrite +.Fa overwrite is tested; if -.Ar overwrite is +.Fa overwrite +is zero, the variable is not reset, otherwise it is reset to the given -.Ar value . +.Fa value . .Pp The .Fn putenv @@ -140,14 +141,14 @@ Successive calls to or .Fn putenv assigning a differently sized -.Ar value +.Fa value to the same -.Ar name +.Fa name will result in a memory leak. The .Fx semantics for these functions (namely, that the contents of -.Ar value +.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. diff --git a/stdlib/getenv.c b/stdlib/FreeBSD/getenv.c similarity index 65% rename from stdlib/getenv.c rename to stdlib/FreeBSD/getenv.c index 103a2d5..aa15989 100644 --- a/stdlib/getenv.c +++ b/stdlib/FreeBSD/getenv.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,27 +31,17 @@ * 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 - -char *__findenv __P((const char *, int *)); - -/* - * getenv -- - * Returns ptr to value associated with name, if any, else NULL. - */ -char * -getenv(name) - const char *name; -{ - int offset; - - return (__findenv(name, &offset)); -} +inline char *__findenv(const char *, int *); /* * __findenv -- @@ -86,26 +52,42 @@ getenv(name) * * This routine *should* be a static; don't use it. */ -char * +inline char * __findenv(name, offset) - register const char *name; + const char *name; int *offset; { - register int len; - register const char *np; - register char **p, *c; - - char **environ = *_NSGetEnviron(); + extern 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; (c = *p) != NULL; ++p) - if (strncmp(c, name, len) == 0 && c[len] == '=') { + 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 (c + len + 1); + return (cp); } + } return (NULL); } + +/* + * getenv -- + * Returns ptr to value associated with name, if any, else NULL. + */ +char * +getenv(name) + const char *name; +{ + int offset; + + return (__findenv(name, &offset)); +} diff --git a/stdlib/FreeBSD/getenv.c.patch b/stdlib/FreeBSD/getenv.c.patch new file mode 100644 index 0000000..12472a3 --- /dev/null +++ b/stdlib/FreeBSD/getenv.c.patch @@ -0,0 +1,19 @@ +--- getenv.c.orig Mon Apr 28 16:37:26 2003 ++++ getenv.c Sat May 3 14:29:07 2003 +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + inline char *__findenv(const char *, int *); + +@@ -57,7 +58,7 @@ + const char *name; + int *offset; + { +- extern char **environ; ++ char **environ = *_NSGetEnviron(); + int len, i; + const char *np; + char **p, *cp; diff --git a/stdlib/getopt.3 b/stdlib/FreeBSD/getopt.3 similarity index 98% rename from stdlib/getopt.3 rename to stdlib/FreeBSD/getopt.3 index 7b08faf..828b786 100644 --- a/stdlib/getopt.3 +++ b/stdlib/FreeBSD/getopt.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 -.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.20 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.21 2002/12/04 18:57:45 ru Exp $ .\" .Dd April 27, 1995 .Dt GETOPT 3 @@ -145,7 +145,7 @@ function encounters a character not found in the string .Va optstring or detects a missing option argument it writes an error message to the -.Em stderr +.Dv stderr and returns .Ql ?\& . Setting diff --git a/stdlib/getopt.c b/stdlib/FreeBSD/getopt.c similarity index 72% rename from stdlib/getopt.c rename to stdlib/FreeBSD/getopt.c index 99f5192..871db61 100644 --- a/stdlib/getopt.c +++ b/stdlib/FreeBSD/getopt.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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, 1994 * The Regents of the University of California. All rights reserved. @@ -55,12 +31,19 @@ * 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.6 2002/03/29 22:43:42 markm Exp $"); +#include "namespace.h" #include #include #include +#include "un-namespace.h" -#include +#include "libc_private.h" int opterr = 1, /* if error message should be printed */ optind = 1, /* index into parent argv vector */ @@ -82,7 +65,6 @@ getopt(nargc, nargv, ostr) char * const *nargv; const char *ostr; { - char *__progname = *(*_NSGetArgv()); static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ @@ -90,27 +72,27 @@ getopt(nargc, nargv, ostr) optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; - return (EOF); + return (-1); } if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; - return (EOF); + return (-1); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, - * assume it means EOF. + * assume it means -1. */ if (optopt == (int)'-') - return (EOF); + return (-1); if (!*place) ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", __progname, optopt); + if (opterr && *ostr != ':' && optopt != BADCH) + (void)fprintf(stderr, "%s: illegal option -- %c\n", + _getprogname(), optopt); return (BADCH); } if (*++oli != ':') { /* don't need argument */ @@ -128,7 +110,7 @@ getopt(nargc, nargv, ostr) if (opterr) (void)fprintf(stderr, "%s: option requires an argument -- %c\n", - __progname, optopt); + _getprogname(), optopt); return (BADCH); } else /* white space */ diff --git a/stdlib/FreeBSD/getopt_long.3 b/stdlib/FreeBSD/getopt_long.3 new file mode 100644 index 0000000..4e7c401 --- /dev/null +++ b/stdlib/FreeBSD/getopt_long.3 @@ -0,0 +1,400 @@ +.\" $NetBSD: getopt_long.3,v 1.8 2002/06/03 12:01:43 wiz Exp $ +.\" +.\" 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. +.\" +.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 +.\" $FreeBSD: src/lib/libc/stdlib/getopt_long.3,v 1.3 2002/12/18 12:45:10 ru Exp $ +.\" +.Dd April 1, 2000 +.Dt GETOPT_LONG 3 +.Os +.Sh NAME +.Nm getopt_long +.Nd get long options from command line argument list +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In getopt.h +.Ft int +.Fo getopt_long +.Fa "int argc" "char * const *argv" "const char *optstring" +.Fa "struct option *long options" "int *index" +.Fc +.Sh DESCRIPTION +The +.Fn getopt_long +function is similar to +.Xr getopt 3 +but it accepts options in two forms: words and characters. +The +.Fn getopt_long +function provides a superset of the functionality of +.Xr getopt 3 . +The +.Fn getopt_long +function +can be used in two ways. +In the first way, every long option understood +by the program has a corresponding short option, and the option +structure is only used to translate from long options to short +options. +When used in this fashion, +.Fn getopt_long +behaves identically to +.Xr getopt 3 . +This is a good way to add long option processing to an existing program +with the minimum of rewriting. +.Pp +In the second mechanism, a long option sets a flag in the +.Vt option +structure passed, or will store a pointer to the command line argument +in the +.Vt option +structure passed to it for options that take arguments. +Additionally, +the long option's argument may be specified as a single argument with +an equal sign, e.g., +.Pp +.Dl "myprogram --myoption=somevalue" +.Pp +When a long option is processed, the call to +.Fn getopt_long +will return 0. +For this reason, long option processing without +shortcuts is not backwards compatible with +.Xr getopt 3 . +.Pp +It is possible to combine these methods, providing for long options +processing with short option equivalents for some options. +Less +frequently used options would be processed as long options only. +.Pp +The +.Fn getopt_long +call requires a structure to be initialized describing the long +options. +The structure is: +.Bd -literal -offset indent +struct option { + char *name; + int has_arg; + int *flag; + int val; +}; +.Ed +.Pp +The +.Va name +field should contain the option name without the leading double dash. +.Pp +The +.Va has_arg +field should be one of: +.Pp +.Bl -tag -width ".Dv optional_argument" -offset indent -compact +.It Dv no_argument +no argument to the option is expect +.It Dv required_argument +an argument to the option is required +.It Li optional_argument +an argument to the option may be presented. +.El +.Pp +If +.Va flag +is not +.Dv NULL , +then the integer pointed to by it will be set to the +value in the +.Va val +field. +If the +.Va flag +field is +.Dv NULL , +then the +.Va val +field will be returned. +Setting +.Va flag +to +.Dv NULL +and setting +.Va val +to the corresponding short option will make this function act just +like +.Xr getopt 3 . +.Sh EXAMPLES +.Bd -literal -compact +extern char *optarg; +extern int optind; +int bflag, ch, fd; +int daggerset; + +/* options descriptor */ +static struct option longopts[] = { + { "buffy", no_argument, 0, 'b' }, + { "floride", required_argument, 0, 'f' }, + { "daggerset", no_argument, \*[Am]daggerset, 1 }, + { 0, 0, 0, 0 } +}; + +bflag = 0; +while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) + switch(ch) { + case 'b': + bflag = 1; + break; + case 'f': + if ((fd = open(optarg, O_RDONLY, 0)) \*[Lt] 0) { + (void)fprintf(stderr, + "myname: %s: %s\en", optarg, strerror(errno)); + exit(1); + } + break; + case 0: + if(daggerset) { + fprintf(stderr,"Buffy will use her dagger to " + "apply floride to dracula's teeth\en"); + } + break; + case '?': + default: + usage(); +} +argc -= optind; +argv += optind; +.Ed +.Sh IMPLEMENTATION DIFFERENCES +This section describes differences to the +.Tn GNU +implementation +found in glibc-2.1.3: +.Bl -bullet +.It +Handling of +.Ql - +as first char of option string in presence of +environment variable +.Ev POSIXLY_CORRECT : +.Bl -tag -width ".Nx" +.It Tn GNU +ignores +.Ev POSIXLY_CORRECT +and returns non-options as +arguments to option '\e1'. +.It Nx +honors +.Ev POSIXLY_CORRECT +and stops at the first non-option. +.El +.It +Handling of +.Ql :: +in options string in presence of +.Ev POSIXLY_CORRECT : +.Bl -tag -width ".Nx" +.It Both +.Tn GNU +and +.Nx +ignore +.Ev POSIXLY_CORRECT +here and take +.Ql :: +to +mean the preceding option takes an optional argument. +.El +.It +Return value in case of missing argument if first character +(after +.Ql + +or +.Ql - ) +in option string is not +.Ql \&: : +.Bl -tag -width ".Nx" +.It Tn GNU +returns +.Ql \&? +.It Nx +returns +.Ql \&: +(since +.Nx Ns 's +.Fn getopt +does). +.El +.It +Handling of +.Ql --a +in getopt: +.Bl -tag -width ".Nx" +.It Tn GNU +parses this as option +.Ql - , +option +.Ql a . +.It Nx +parses this as +.Ql -- , +and returns \-1 (ignoring the +.Ql a ) . +(Because the original +.Fn getopt +does.) +.El +.It +Setting of +.Va optopt +for long options with +.Va flag +!= +.Dv NULL : +.Bl -tag -width ".Nx" +.It Tn GNU +sets +.Va optopt +to +.Va val . +.It Nx +sets +.Va optopt +to 0 (since +.Va val +would never be returned). +.El +.It +Handling of +.Ql -W +with +.Ql W ; +in option string in +.Fn getopt +(not +.Fn getopt_long ) : +.Bl -tag -width ".Nx" +.It Tn GNU +causes a segfault. +.It Nx +returns \-1, with +.Va optind +pointing past the argument of +.Ql -W +(as if +.Ql "-W arg" +were +.Ql --arg , +and thus +.Ql -- +had been found). +.\" How should we treat W; in the option string when called via +.\" getopt? Ignore the ';' or treat it as a ':'? Issue a warning? +.El +.It +Setting of +.Va optarg +for long options without an argument that are +invoked via +.Ql -W +.Ql ( W ; +in option string): +.Bl -tag -width ".Nx" +.It Tn GNU +sets +.Va optarg +to the option name (the argument of +.Ql -W ) . +.It Nx +sets +.Va optarg +to +.Dv NULL +(the argument of the long option). +.El +.It +Handling of +.Ql -W +with an argument that is not (a prefix to) a known +long option +.Ql ( W ; +in option string): +.Bl -tag -width ".Nx" +.It Tn GNU +returns +.Ql -W +with +.Va optarg +set to the unknown option. +.It Nx +treats this as an error (unknown option) and returns +.Ql \&? +with +.Va optopt +set to 0 and +.Va optarg +set to +.Dv NULL +(as +.Tn GNU Ns 's +man page documents). +.El +.It +The error messages are different. +.It +.Nx +does not permute the argument vector at the same points in +the calling sequence as +.Tn GNU +does. +The aspects normally used by +the caller (ordering after \-1 is returned, value of +.Va optind +relative +to current positions) are the same, though. +(We do fewer variable swaps.) +.El +.Sh SEE ALSO +.Xr getopt 3 +.Sh HISTORY +The +.Fn getopt_long +function first appeared in +.Tn GNU +libiberty. +The first +.Nx +implementation appeared in 1.5. +.Sh BUGS +The implementation can completely replace +.Xr getopt 3 , +but right now we are using separate code. diff --git a/stdlib/FreeBSD/getopt_long.c b/stdlib/FreeBSD/getopt_long.c new file mode 100644 index 0000000..6ea873c --- /dev/null +++ b/stdlib/FreeBSD/getopt_long.c @@ -0,0 +1,494 @@ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ +/* $FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.2 2002/10/16 22:18:42 alfred Exp $ */ + +/*- + * 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. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include +#include +#include +#include +#include + +/* not part of the original file */ +#ifndef _DIAGASSERT +#define _DIAGASSERT(X) +#endif + +#if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND +#define REPLACE_GETOPT +#endif + +#ifdef REPLACE_GETOPT +#ifdef __weak_alias +__weak_alias(getopt,_getopt) +#endif +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 */ +#elif HAVE_CONFIG_H && !HAVE_DECL_OPTRESET +static int optreset; +#endif + +#ifdef __weak_alias +__weak_alias(getopt_long,_getopt_long) +#endif + +#if !HAVE_GETOPT_LONG +#define IGNORE_FIRST (*options == '-' || *options == '+') +#define PRINT_ERROR ((opterr) && ((*options != ':') \ + || (IGNORE_FIRST && options[1] != ':'))) +#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) +#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) +/* XXX: GNU ignores PC if *options == '-' */ +#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((IGNORE_FIRST && options[1] == ':') \ + || (*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *); +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 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 illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(a, b) + 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(panonopt_start, panonopt_end, opt_end, nargv) + int panonopt_start; + int panonopt_end; + int opt_end; + char * const *nargv; +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + _DIAGASSERT(nargv != NULL); + + /* + * 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; + } + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + * Returns -2 if -- is found (can be long option or end of options marker). + */ +static int +getopt_internal(nargc, nargv, options) + int nargc; + char * const *nargv; + const char *options; +{ + char *oli; /* option letter list index */ + int optchar; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + optarg = NULL; + + /* + * XXX Some programs (like rsyncd) expect to be able to + * XXX re-initialize optind to 0 and have getopt_long(3) + * XXX properly function again. Work around this braindamage. + */ + if (optind == 0) + optind = 1; + + 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]) != '-') + || (place[1] == '\0')) { /* found non-option */ + place = EMSG; + if (IN_ORDER) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return INORDER; + } + if (!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 (place[1] && *++place == '-') { /* found "--" */ + place++; + return -2; + } + } + if ((optchar = (int)*place++) == (int)':' || + (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { + /* option letter unknown or ':' */ + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return BADCH; + } + if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ + /* XXX: what if no long options provided (called by getopt)? */ + if (*place) + return -2; + + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return BADARG; + } else /* white space */ + place = nargv[optind]; + /* + * Handle -W arg the same as --arg (which causes getopt to + * stop parsing). + */ + return -2; + } + 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]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return optchar; +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the real getopt] + */ +int +getopt(nargc, nargv, options) + int nargc; + char * const *nargv; + const char *options; +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + ++optind; + /* + * 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; + retval = -1; + } + return retval; +} +#endif + +/* + * 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; +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* idx may be NULL */ + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + place = EMSG; + + if (*current_argv == '\0') { /* found "--" */ + /* + * 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; + } + 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) == + (unsigned)current_argv_len) { + /* exact match */ + match = i; + break; + } + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (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, (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; + return BADARG; + } + 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, 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 (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return BADCH; + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (idx) + *idx = match; + } + return retval; +} +#endif /* !GETOPT_LONG */ diff --git a/stdlib/getsubopt.3 b/stdlib/FreeBSD/getsubopt.3 similarity index 100% rename from stdlib/getsubopt.3 rename to stdlib/FreeBSD/getsubopt.3 diff --git a/stdlib/getsubopt.c b/stdlib/FreeBSD/getsubopt.c similarity index 72% rename from stdlib/getsubopt.c rename to stdlib/FreeBSD/getsubopt.c index 35922a6..6a3cf2b 100644 --- a/stdlib/getsubopt.c +++ b/stdlib/FreeBSD/getsubopt.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,9 +31,15 @@ * 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.5 2003/01/03 23:31:50 tjr Exp $"); -#include #include +#include +#include /* * The SVID interface to getsubopt provides no way of figuring out which @@ -67,12 +49,13 @@ */ char *suboptarg; +int getsubopt(optionp, tokens, valuep) - register char **optionp, **valuep; - register char * const *tokens; + char **optionp, **valuep; + char * const *tokens; { - register int cnt; - register char *p; + int cnt; + char *p; suboptarg = *valuep = NULL; @@ -101,7 +84,7 @@ getsubopt(optionp, tokens, valuep) *p = '\0'; for (*valuep = ++p; *p && *p != ',' && *p != ' ' && *p != '\t'; ++p); - if (*p) + if (*p) *p++ = '\0'; } else *p++ = '\0'; diff --git a/stdlib/FreeBSD/grantpt.3 b/stdlib/FreeBSD/grantpt.3 new file mode 100644 index 0000000..02ba39c --- /dev/null +++ b/stdlib/FreeBSD/grantpt.3 @@ -0,0 +1,224 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD: src/lib/libc/stdlib/grantpt.3,v 1.1 2003/01/02 20:44:41 jmallett Exp $ +.\" +.Dd December 23, 2002 +.Os +.Dt GRANTPT 3 +.Sh NAME +.Nm grantpt , +.Nm ptsname , +.Nm unlockpt , +.Nm posix_openpt +.Nd pseudo-terminal access functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn grantpt "int fildes" +.Ft char * +.Fn ptsname "int fildes" +.Ft int +.Fn unlockpt "int fildes" +.In fcntl.h +.Ft int +.Fn posix_openpt "int mode" +.Sh DESCRIPTION +The +.Fn grantpt , +.Fn ptsname , +.Fn unlockpt , +and +.Fn posix_openpt +functions allow access to pseudo-terminal devices. +The first three functions accept a file descriptor +that references the master half of a pseudo-terminal pair. +This file descriptor is created with +.Fn posix_openpt . +.Pp +The +.Fn grantpt +function is used to establish ownership and permissions +of the slave device counterpart to the master device +specified with +.Va fildes . +The slave device's ownership is set to the real user ID +of the calling process, and the permissions are set to +user readable-writable and group writable. +The group owner of the slave device is also set to the +group "tty" if it exists on the system; otherwise, it +is left untouched. +.Pp +The +.Fn ptsname +function returns the full pathname of the slave device +counterpart to the master device specified with +.Va fildes . +This value can be used +to subsequently open the appropriate slave after +.Fn posix_openpt +and +.Fn grantpt +have been called. +.Pp +The +.Fn unlockpt +function clears the lock held on the pseudo-terminal pair +for the master device specified with +.Va fildes . +.Pp +The +.Fn posix_openpt +function opens the first available master pseudo-terminal +device and returns a descriptor to it. +.Va mode +specifies the flags used for opening the device: +.Bl -tag -width O_NOCTTY +.It Dv O_RDWR +Open for reading and writing. +.It Dv O_NOCTTY +If set, do not allow the terminal to become +the controlling terminal for the calling process. +.El +.Sh RETURN VALUES +The +.Fn grantpt +and +.Fn unlockpt +functions return 0 on success; otherwise -1 is returned and +.Va errno +is set to indicate the error. +.Pp +The +.Fn ptsname +function returns a pointer to the name +of the slave device on success; +otherwise a NULL pointer is returned and +.Va errno +is set to indicate the error. +.Pp +The +.Fn posix_openpt +function returns a file descriptor to the first +available master pseudo-terminal device on success; +otherwise -1 is returned and +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn grantpt , +.Fn ptsname , +and +.Fn unlockpt +functions may fail and set +.Va errno +to: +.Bl -tag -width Er +.It EINVAL +.Va fildes +is not a master pseudo-terminal device. +.El +.Pp +In addition, the +.Fn grantpt +function may set +.Va errno +to: +.Bl -tag -width Er +.It EACCES +The slave pseudo-terminal device could not be accessed. +.El +.Pp +The +.Fn posix_openpt +function may fail and set +.Va errno +to: +.Bl -tag -width Er +.It EINVAL +.Va mode +consists an an invalid mode bit. +.It EAGAIN +The system has no available pseudo-terminal devices. +.El +.Pp +The +.Fn grantpt , +.Fn ptsname , +and +.Fn unlockpt +functions may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr fstat 2 . +.Pp +The +.Fn posix_openpt +function may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr open 2 . +.Sh SEE ALSO +.Xr open 2 , +.Xr pty 4 , +.Xr tty 4 +.Sh STANDARDS +The +.Fn grantpt , +.Fn ptsname , +.Fn unlockpt , +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/FreeBSD/grantpt.c b/stdlib/FreeBSD/grantpt.c new file mode 100644 index 0000000..9902c54 --- /dev/null +++ b/stdlib/FreeBSD/grantpt.c @@ -0,0 +1,259 @@ +/* + * 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/hcreate.3 b/stdlib/FreeBSD/hcreate.3 similarity index 88% rename from stdlib/hcreate.3 rename to stdlib/FreeBSD/hcreate.3 index 1619c98..cc87dd6 100644 --- a/stdlib/hcreate.3 +++ b/stdlib/FreeBSD/hcreate.3 @@ -1,4 +1,4 @@ -.\" $FreeBSD: src/lib/libc/stdlib/hcreate.3,v 1.2 2001/07/09 15:54:36 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/hcreate.3,v 1.3 2003/03/12 14:18:14 dwmalone Exp $ .\" .Dd May 8, 2001 .Os @@ -44,6 +44,12 @@ function disposes of the search table, and may be followed by another call to After the call to .Fn hdestroy , the data can no longer be considered accessible. +The +.Fn hdestroy +function calls +.Xr free 3 +for each comparison key in the search table +but not the data item associated with the key. .Pp The .Fn hsearch @@ -88,6 +94,20 @@ Unsuccessful resolution is indicated by the return of a .Dv NULL pointer. +.Pp +The comparison key (passed to +.Fn hsearch +as +.Fa item.key ) +must be allocated using +.Xr malloc 3 +if +.Fa action +is +.Dv ENTER +and +.Fn hdestroy +is called. .Sh RETURN VALUES The .Fn hcreate @@ -132,6 +152,7 @@ table and prints it out. #include #include #include +#include struct info { /* This is the info stored in the table */ int age, room; /* other than the key. */ @@ -142,9 +163,8 @@ struct info { /* This is the info stored in the table */ int main(void) { - char string_space[NUM_EMPL*20]; /* Space to store strings. */ + char str[BUFSIZ]; /* Space to read string */ struct info info_space[NUM_EMPL]; /* Space to store employee info. */ - char *str_ptr = string_space; /* Next space in string_space. */ struct info *info_ptr = info_space; /* Next space in info_space. */ ENTRY item; ENTRY *found_item; /* Name to look for in table. */ @@ -154,12 +174,11 @@ main(void) /* Create table; no error checking is performed. */ (void) hcreate(NUM_EMPL); - while (scanf("%s%d%d", str_ptr, &info_ptr->age, + while (scanf("%s%d%d", str, &info_ptr->age, &info_ptr->room) != EOF && i++ < NUM_EMPL) { /* Put information in structure, and structure in item. */ - item.key = str_ptr; + item.key = strdup(str); item.data = info_ptr; - str_ptr += strlen(str_ptr) + 1; info_ptr++; /* Put item into table. */ (void) hsearch(item, ENTER); @@ -177,6 +196,7 @@ main(void) } else (void)printf("no such employee %s\en", name_to_find); } + hdestroy(); return 0; } .Ed diff --git a/stdlib/FreeBSD/hcreate.c b/stdlib/FreeBSD/hcreate.c new file mode 100644 index 0000000..6ab33e5 --- /dev/null +++ b/stdlib/FreeBSD/hcreate.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/heapsort.c b/stdlib/FreeBSD/heapsort.c similarity index 83% rename from stdlib/heapsort.c rename to stdlib/FreeBSD/heapsort.c index 80d87aa..e846be2 100644 --- a/stdlib/heapsort.c +++ b/stdlib/FreeBSD/heapsort.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,11 +34,15 @@ * 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 #include +#include /* * Swap two areas of size number of bytes. Although qsort(3) permits random @@ -163,10 +143,10 @@ int heapsort(vbase, nmemb, size, compar) void *vbase; size_t nmemb, size; - int (*compar) __P((const void *, const void *)); + int (*compar)(const void *, const void *); { - register int cnt, i, j, l; - register char tmp, *tmp1, *tmp2; + int cnt, i, j, l; + char tmp, *tmp1, *tmp2; char *base, *k, *p, *t; if (nmemb <= 1) diff --git a/stdlib/FreeBSD/imaxabs.3 b/stdlib/FreeBSD/imaxabs.3 new file mode 100644 index 0000000..ac520b2 --- /dev/null +++ b/stdlib/FreeBSD/imaxabs.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/imaxabs.3,v 1.2 2001/11/21 16:19:50 ru Exp $ +.\" +.Dd November 14, 2001 +.Dt IMAXABS 3 +.Os +.Sh NAME +.Nm imaxabs +.Nd returns absolute value +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In inttypes.h +.Ft intmax_t +.Fn imaxabs "intmax_t j" +.Sh DESCRIPTION +The +.Fn imaxabs +function returns the absolute value of +.Fa j . +.Sh SEE ALSO +.Xr abs 3 , +.Xr fabs 3 , +.Xr hypot 3 , +.Xr labs 3 , +.Xr llabs 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn imaxabs +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn imaxabs +function first appeared in +.Fx 5.0 . +.Sh BUGS +The absolute value of the most negative integer remains negative. diff --git a/stdlib/FreeBSD/imaxabs.c b/stdlib/FreeBSD/imaxabs.c new file mode 100644 index 0000000..531de24 --- /dev/null +++ b/stdlib/FreeBSD/imaxabs.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/FreeBSD/imaxdiv.3 b/stdlib/FreeBSD/imaxdiv.3 new file mode 100644 index 0000000..2a6bad5 --- /dev/null +++ b/stdlib/FreeBSD/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 +and returns the stored result 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/FreeBSD/imaxdiv.c b/stdlib/FreeBSD/imaxdiv.c new file mode 100644 index 0000000..ff3087b --- /dev/null +++ b/stdlib/FreeBSD/imaxdiv.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/FreeBSD/insque.3 b/stdlib/FreeBSD/insque.3 new file mode 100644 index 0000000..06f93bf --- /dev/null +++ b/stdlib/FreeBSD/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 *element1" "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/FreeBSD/insque.c b/stdlib/FreeBSD/insque.c new file mode 100644 index 0000000..92984b0 --- /dev/null +++ b/stdlib/FreeBSD/insque.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/labs.3 b/stdlib/FreeBSD/labs.3 similarity index 94% rename from stdlib/labs.3 rename to stdlib/FreeBSD/labs.3 index 8cd757f..d496b30 100644 --- a/stdlib/labs.3 +++ b/stdlib/FreeBSD/labs.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)labs.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.7 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.9 2002/12/18 13:33:03 ru Exp $ .\" -.Dd June 4, 1993 +.Dd November 14, 2001 .Dt LABS 3 .Os .Sh NAME @@ -53,11 +53,13 @@ The .Fn labs function returns the absolute value of the long integer -.Ar j . +.Fa j . .Sh SEE ALSO .Xr abs 3 , .Xr cabs 3 , .Xr floor 3 , +.Xr imaxabs 3 , +.Xr llabs 3 , .Xr math 3 .Sh STANDARDS The diff --git a/stdlib/labs.c b/stdlib/FreeBSD/labs.c similarity index 65% rename from stdlib/labs.c rename to stdlib/FreeBSD/labs.c index 02adfe1..42e63d1 100644 --- a/stdlib/labs.c +++ b/stdlib/FreeBSD/labs.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,6 +34,8 @@ #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 diff --git a/stdlib/ldiv.3 b/stdlib/FreeBSD/ldiv.3 similarity index 92% rename from stdlib/ldiv.3 rename to stdlib/FreeBSD/ldiv.3 index c9f168e..c75b8be 100644 --- a/stdlib/ldiv.3 +++ b/stdlib/FreeBSD/ldiv.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ldiv.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.7 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.9 2002/12/18 13:33:03 ru Exp $ .\" -.Dd June 4, 1993 +.Dd November 14, 2001 .Dt LDIV 3 .Os .Sh NAME @@ -53,21 +53,23 @@ The .Fn ldiv function computes the value -.Ar num/denom +.Fa num Ns / Ns Fa denom and returns the quotient and remainder in a structure named -.Ar ldiv_t +.Vt ldiv_t that contains two -.Em long integer +.Vt long members named -.Ar quot +.Va quot and -.Ar rem . +.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 . +.St -isoC-99 . diff --git a/stdlib/ldiv.c b/stdlib/FreeBSD/ldiv.c similarity index 67% rename from stdlib/ldiv.c rename to stdlib/FreeBSD/ldiv.c index 94dffe2..560d5c2 100644 --- a/stdlib/ldiv.c +++ b/stdlib/FreeBSD/ldiv.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -58,6 +34,11 @@ * 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 */ diff --git a/stdlib/FreeBSD/llabs.3 b/stdlib/FreeBSD/llabs.3 new file mode 100644 index 0000000..a8238da --- /dev/null +++ b/stdlib/FreeBSD/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 j" +.Sh DESCRIPTION +The +.Fn llabs +function returns the absolute value of +.Fa j . +.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/FreeBSD/llabs.c b/stdlib/FreeBSD/llabs.c new file mode 100644 index 0000000..4721fce --- /dev/null +++ b/stdlib/FreeBSD/llabs.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/FreeBSD/lldiv.3 b/stdlib/FreeBSD/lldiv.3 new file mode 100644 index 0000000..96ecf1a --- /dev/null +++ b/stdlib/FreeBSD/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 +and 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/FreeBSD/lldiv.c b/stdlib/FreeBSD/lldiv.c new file mode 100644 index 0000000..c9a4853 --- /dev/null +++ b/stdlib/FreeBSD/lldiv.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/FreeBSD/lsearch.3 b/stdlib/FreeBSD/lsearch.3 new file mode 100644 index 0000000..fd79b9a --- /dev/null +++ b/stdlib/FreeBSD/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 lsearch , +.Nm lfind +.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" +.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" +.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 and compare each element with +the one to be sought using 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/FreeBSD/lsearch.c b/stdlib/FreeBSD/lsearch.c new file mode 100644 index 0000000..791bc49 --- /dev/null +++ b/stdlib/FreeBSD/lsearch.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/memory.3 b/stdlib/FreeBSD/memory.3 similarity index 100% rename from stdlib/memory.3 rename to stdlib/FreeBSD/memory.3 diff --git a/stdlib/merge.c b/stdlib/FreeBSD/merge.c similarity index 84% rename from stdlib/merge.c rename to stdlib/FreeBSD/merge.c index de68126..711b9cd 100644 --- a/stdlib/merge.c +++ b/stdlib/FreeBSD/merge.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,6 +34,11 @@ * 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 @@ -79,8 +60,8 @@ #include #include -static void setup __P((u_char *, u_char *, size_t, size_t, int (*)())); -static void insertionsort __P((u_char *, size_t, size_t, int (*)())); +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 *) @@ -101,7 +82,7 @@ static void insertionsort __P((u_char *, size_t, size_t, int (*)())); 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 @@ -119,12 +100,12 @@ int mergesort(base, nmemb, size, cmp) void *base; size_t nmemb; - register size_t size; - int (*cmp) __P((const void *, const void *)); + size_t size; + int (*cmp)(const void *, const void *); { - register int i, sense; + int i, sense; int big, iflag; - register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; + 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. */ @@ -132,6 +113,9 @@ mergesort(base, nmemb, size, cmp) return (-1); } + if (nmemb == 0) + return (0); + /* * XXX * Stupid subtraction for the Cray. @@ -168,7 +152,7 @@ mergesort(base, nmemb, size, cmp) sense = 0; } if (!big) { /* here i = 0 */ -LINEAR: while ((b += size) < t && cmp(q, b) >sense) + while ((b += size) < t && cmp(q, b) >sense) if (++i == 6) { big = 1; goto EXPONENTIAL; @@ -185,11 +169,11 @@ EXPONENTIAL: for (i = size; ; i <<= 1) } else if ((*cmp)(q, p) <= sense) { t = p; if (i == size) - big = 0; + big = 0; goto FASTCASE; } else b = p; -SLOWCASE: while (t > b+size) { + while (t > b+size) { i = (((t - b) / size) >> 1) * size; if ((*cmp)(q, p = b + i) <= sense) t = p; @@ -278,7 +262,7 @@ COPY: b = t; void setup(list1, list2, n, size, cmp) size_t n, size; - int (*cmp) __P((const void *, const void *)); + int (*cmp)(const void *, const void *); u_char *list1, *list2; { int i, length, size2, tmp, sense; @@ -353,7 +337,7 @@ static void insertionsort(a, n, size, cmp) u_char *a; size_t n, size; - int (*cmp) __P((const void *, const void *)); + int (*cmp)(const void *, const void *); { u_char *ai, *s, *t, *u, tmp; int i; diff --git a/stdlib/putenv.c b/stdlib/FreeBSD/putenv.c similarity index 66% rename from stdlib/putenv.c rename to stdlib/FreeBSD/putenv.c index a3fe0cf..c8f3b60 100644 --- a/stdlib/putenv.c +++ b/stdlib/FreeBSD/putenv.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 diff --git a/stdlib/qsort.3 b/stdlib/FreeBSD/qsort.3 similarity index 78% rename from stdlib/qsort.3 rename to stdlib/FreeBSD/qsort.3 index 9f591b9..c1a17e7 100644 --- a/stdlib/qsort.3 +++ b/stdlib/FreeBSD/qsort.3 @@ -34,24 +34,47 @@ .\" SUCH DAMAGE. .\" .\" @(#)qsort.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.10 2001/09/07 14:46:35 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.13 2002/12/18 12:45:10 ru Exp $ .\" -.Dd June 4, 1993 +.Dd September 7, 2002 .Dt QSORT 3 .Os .Sh NAME -.Nm qsort , heapsort , mergesort +.Nm qsort , qsort_r , heapsort , mergesort .Nd sort functions .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .Ft void -.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" +.Fo qsort +.Fa "void *base" +.Fa "size_t nmemb" +.Fa "size_t size" +.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 "void *thunk" +.Fa "int \*[lp]*compar\*[rp]\*[lp]void *, const void *, const void *\*[rp]" +.Fc .Ft int -.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" +.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 -.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)" +.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 @@ -74,7 +97,9 @@ objects, the initial member of which is pointed to by .Fa base . The size of each object is specified by .Fa size . -.Fn Mergesort +The +.Fn mergesort +function behaves similarly, but .Em requires that @@ -94,33 +119,53 @@ 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 functions -.Fn qsort +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 function +The .Fn mergesort -is stable. +algorithm is stable. .Pp The .Fn qsort -function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm, +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 D.E. Knuth's Algorithm Q. -.Fn Qsort +.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 J.W.J. William's ``heapsort'' algorithm, +function is an implementation of J.W.J. William's +.Dq heapsort +algorithm, a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. -.Fn Heapsort +.Sy Heapsort takes O N lg N worst-case time. Its .Em only @@ -136,7 +181,9 @@ requires additional memory of size .Fa nmemb * .Fa size bytes; it should be used only when space is not at a premium. -.Fn Mergesort +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 @@ -151,8 +198,10 @@ untrue. .Sh RETURN VALUES The .Fn qsort -function -returns no value. +and +.Fn qsort_r +functions +return no value. .Pp .Rv -std heapsort mergesort .Sh ERRORS @@ -173,9 +222,11 @@ argument to is less than .Dq "sizeof(void *) / 2" . .It Bq Er ENOMEM -.Fn Heapsort +The +.Fn heapsort or .Fn mergesort +functions were unable to allocate memory. .El .Sh COMPATIBILITY diff --git a/stdlib/qsort.c b/stdlib/FreeBSD/qsort.c similarity index 62% rename from stdlib/qsort.c rename to stdlib/FreeBSD/qsort.c index 7926c7b..f1add73 100644 --- a/stdlib/qsort.c +++ b/stdlib/FreeBSD/qsort.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,12 +31,21 @@ * 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 #include -static inline char *med3 __P((char *, char *, char *, int (*)())); -static inline void swapfunc __P((char *, char *, int, int)); +#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 *); +static inline void swapfunc(char *, char *, int, int); #define min(a, b) (a) < (b) ? a : b @@ -69,10 +54,10 @@ static inline void swapfunc __P((char *, char *, int, int)); */ #define swapcode(TYPE, parmi, parmj, n) { \ long i = (n) / sizeof (TYPE); \ - register TYPE *pi = (TYPE *) (parmi); \ - register TYPE *pj = (TYPE *) (parmj); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ do { \ - register TYPE t = *pi; \ + TYPE t = *pi; \ *pi++ = *pj; \ *pj++ = t; \ } while (--i > 0); \ @@ -86,7 +71,7 @@ swapfunc(a, b, n, swaptype) char *a, *b; int n, swaptype; { - if(swaptype <= 1) + if(swaptype <= 1) swapcode(long, a, b, n) else swapcode(char, a, b, n) @@ -102,21 +87,32 @@ swapfunc(a, b, n, 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(a, b, c, cmp) - char *a, *b, *c; - int (*cmp)(); +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk +#ifndef I_AM_QSORT_R +__unused +#endif +) { - return cmp(a, b) < 0 ? - (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) - :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); + 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(a, n, es, cmp) - void *a; - size_t n, es; - int (*cmp)(); +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; @@ -124,30 +120,31 @@ qsort(a, n, es, cmp) loop: SWAPINIT(a, es); swap_cnt = 0; if (n < 7) { - for (pm = a + es; pm < (char *) a + n * es; pm += es) - for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; + 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 = a + (n / 2) * es; + pm = (char *)a + (n / 2) * es; if (n > 7) { pl = a; - pn = a + (n - 1) * es; + pn = (char *)a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; - pl = med3(pl, pl + d, pl + 2 * d, cmp); - pm = med3(pm - d, pm, pm + d, cmp); - pn = med3(pn - 2 * d, pn - d, pn, cmp); + 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); + pm = med3(pl, pm, pn, cmp, thunk); } swap(a, pm); - pa = pb = a + es; + pa = pb = (char *)a + es; - pc = pd = a + (n - 1) * es; + pc = pd = (char *)a + (n - 1) * es; for (;;) { - while (pb <= pc && (r = cmp(pb, a)) <= 0) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { if (r == 0) { swap_cnt = 1; swap(pa, pb); @@ -155,7 +152,7 @@ loop: SWAPINIT(a, es); } pb += es; } - while (pb <= pc && (r = cmp(pc, a)) >= 0) { + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { if (r == 0) { swap_cnt = 1; swap(pc, pd); @@ -171,21 +168,26 @@ loop: SWAPINIT(a, es); pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ - for (pm = a + es; pm < (char *) a + n * es; pm += es) - for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; + 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 = a + n * es; + 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); - if ((r = pd - pc) > es) { +#endif + if ((r = pd - pc) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; diff --git a/stdlib/FreeBSD/qsort_r.c b/stdlib/FreeBSD/qsort_r.c new file mode 100644 index 0000000..f7c0e54 --- /dev/null +++ b/stdlib/FreeBSD/qsort_r.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.c" diff --git a/stdlib/FreeBSD/qsort_r.c.patch b/stdlib/FreeBSD/qsort_r.c.patch new file mode 100644 index 0000000..031e772 --- /dev/null +++ b/stdlib/FreeBSD/qsort_r.c.patch @@ -0,0 +1,8 @@ +--- qsort_r.c.orig Mon Apr 28 16:37:26 2003 ++++ qsort_r.c Sat May 3 14:29:49 2003 +@@ -5,4 +5,4 @@ + * $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.c" ++#include "qsort-fbsd.c" diff --git a/stdlib/radixsort.3 b/stdlib/FreeBSD/radixsort.3 similarity index 100% rename from stdlib/radixsort.3 rename to stdlib/FreeBSD/radixsort.3 diff --git a/stdlib/radixsort.c b/stdlib/FreeBSD/radixsort.c similarity index 80% rename from stdlib/radixsort.c rename to stdlib/FreeBSD/radixsort.c index 136a2a5..7f14966 100644 --- a/stdlib/radixsort.c +++ b/stdlib/FreeBSD/radixsort.c @@ -1,33 +1,9 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * * This code is derived from software contributed to Berkeley by - * Peter McIlroy and by Dan Bernstein at New York University, + * 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 @@ -58,16 +34,21 @@ * 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.6 2002/03/22 09:18:34 obrien 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". */ @@ -83,10 +64,10 @@ typedef struct { } stack; static inline void simplesort - __P((const u_char **, int, int, const u_char *, u_int)); -static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int)); -static void r_sort_b __P((const u_char **, - const u_char **, int, int, const u_char *, u_int)); +(const u_char **, int, int, const u_char *, u_int); +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. */ @@ -160,19 +141,13 @@ r_sort_a(a, n, i, tr, endch) const u_char *tr; u_int endch; { - static int *count = NULL, nc, bmin; - register int c; - register const u_char **ak, *r; + 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]; - if( count == NULL ) { - count = malloc(256*sizeof(int)); - if( count == NULL ) - return; - } - /* Set up stack. */ sp = s; push(a, n, i); @@ -257,19 +232,13 @@ r_sort_b(a, ta, n, i, tr, endch) const u_char *tr; u_int endch; { - static int *count = NULL, nc, bmin; - register int c; - register const u_char **ak, **ai; + 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; - if( count == NULL ) { - count = malloc(256*sizeof(int)); - if( count == NULL ) - return; - } - sp = s; push(a, n, i); while (!empty(s)) { @@ -327,15 +296,15 @@ r_sort_b(a, ta, n, i, tr, endch) *--top[tr[(*ak)[i]]] = *ak; } } - + static inline void simplesort(a, n, b, tr, endch) /* insertion sort */ - register const u_char **a; + const u_char **a; int n, b; - register const u_char *tr; + const u_char *tr; u_int endch; { - register u_char ch; + u_char ch; const u_char **ak, **ai, *s, *t; for (ak = a+1; --n >= 1; ak++) diff --git a/stdlib/rand.3 b/stdlib/FreeBSD/rand.3 similarity index 97% rename from stdlib/rand.3 rename to stdlib/FreeBSD/rand.3 index 609c263..66ed9d3 100644 --- a/stdlib/rand.3 +++ b/stdlib/FreeBSD/rand.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)rand.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.12 2001/09/07 14:46:36 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.13 2002/12/18 12:45:10 ru Exp $ .\" .Dd May 25, 1999 .Dt RAND 3 @@ -94,7 +94,9 @@ function initializes a seed using the 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 diff --git a/stdlib/FreeBSD/rand.c b/stdlib/FreeBSD/rand.c new file mode 100644 index 0000000..359e12a --- /dev/null +++ b/stdlib/FreeBSD/rand.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/random.3 b/stdlib/FreeBSD/random.3 similarity index 100% rename from stdlib/random.3 rename to stdlib/FreeBSD/random.3 diff --git a/stdlib/random.c b/stdlib/FreeBSD/random.c similarity index 74% rename from stdlib/random.c rename to stdlib/FreeBSD/random.c index 83c3926..e5b587e 100644 --- a/stdlib/random.c +++ b/stdlib/FreeBSD/random.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,9 +31,19 @@ * 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.22 2003/02/04 11:24:08 ache Exp $"); +#include "namespace.h" +#include /* for srandomdev() */ +#include /* for srandomdev() */ #include #include +#include /* for srandomdev() */ +#include "un-namespace.h" /* * random.c: @@ -82,7 +68,7 @@ * 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 @@ -94,9 +80,28 @@ * 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 register is the dominant factor. + * 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. */ /* @@ -137,13 +142,15 @@ */ #define MAX_TYPES 5 /* max number of types above */ +#define NSHUFF 100 /* to drop part of seed -> 1st value correlation */ + static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; static long 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); + * 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 @@ -156,12 +163,23 @@ static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; static long 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 */ }; /* @@ -197,6 +215,41 @@ static long rand_deg = DEG_3; static long rand_sep = SEP_3; static long *end_ptr = &randtbl[DEG_3 + 1]; +static inline long good_rand(long); + +static inline long good_rand (x) + long 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. + */ + long 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: * @@ -213,18 +266,64 @@ void srandom(x) unsigned long x; { - register long i; + long i, lim; + state[0] = x; if (rand_type == TYPE_0) - state[0] = x; + lim = NSHUFF; else { - state[0] = x; for (i = 1; i < rand_deg; i++) - state[i] = 1103515245 * state[i - 1] + 12345; + 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]; - for (i = 0; i < 10 * rand_deg; i++) - (void)random(); } } @@ -236,12 +335,12 @@ srandom(x) * 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. * @@ -257,8 +356,8 @@ initstate(seed, arg_state, n) char *arg_state; /* pointer to state array */ long n; /* # bytes of state info */ { - register char *ostate = (char *)(&state[-1]); - register long *long_arg_state = (long *) arg_state; + char *ostate = (char *)(&state[-1]); + long *long_arg_state = (long *) arg_state; if (rand_type == TYPE_0) state[-1] = rand_type; @@ -323,9 +422,9 @@ char * setstate(arg_state) char *arg_state; /* pointer to state array */ { - register long *new_state = (long *) arg_state; - register long type = new_state[0] % MAX_TYPES; - register long rear = new_state[0] / MAX_TYPES; + long *new_state = (long *) arg_state; + long type = new_state[0] % MAX_TYPES; + long rear = new_state[0] / MAX_TYPES; char *ostate = (char *)(&state[-1]); if (rand_type == TYPE_0) @@ -375,12 +474,12 @@ setstate(arg_state) long random() { - register long i; - register long *f, *r; + long i; + long *f, *r; if (rand_type == TYPE_0) { i = state[0]; - state[0] = i = (i * 1103515245 + 12345) & 0x7fffffff; + state[0] = i = (good_rand(i)) & 0x7fffffff; } else { /* * Use local variables rather than static variables for speed. diff --git a/stdlib/reallocf.c b/stdlib/FreeBSD/reallocf.c similarity index 92% rename from stdlib/reallocf.c rename to stdlib/FreeBSD/reallocf.c index c4cd9d9..d502006 100644 --- a/stdlib/reallocf.c +++ b/stdlib/FreeBSD/reallocf.c @@ -22,9 +22,11 @@ * LIABILITY, OR TORT (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/reallocf.c,v 1.3 1999/08/28 00:01:37 peter Exp $ */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/reallocf.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); + #include void * diff --git a/stdlib/realpath.3 b/stdlib/FreeBSD/realpath.3 similarity index 93% rename from stdlib/realpath.3 rename to stdlib/FreeBSD/realpath.3 index 90dc5c0..5fe8c16 100644 --- a/stdlib/realpath.3 +++ b/stdlib/FreeBSD/realpath.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)realpath.3 8.2 (Berkeley) 2/16/94 -.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.10 2001/09/07 14:46:36 asmodai Exp $ +.\" $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 @@ -47,7 +47,7 @@ .In sys/param.h .In stdlib.h .Ft "char *" -.Fn realpath "const char *pathname" "char resolved_path[MAXPATHLEN]" +.Fn realpath "const char *pathname" "char resolved_path[PATH_MAX]" .Sh DESCRIPTION The .Fn realpath @@ -67,7 +67,7 @@ The argument .Em must refer to a buffer capable of storing at least -.Dv MAXPATHLEN +.Dv PATH_MAX characters. .Pp The @@ -99,11 +99,7 @@ The function may fail and set the external variable .Va errno for any of the errors specified for the library functions -.Xr chdir 2 , -.Xr close 2 , -.Xr fchdir 2 , .Xr lstat 2 , -.Xr open 2 , .Xr readlink 2 and .Xr getcwd 3 . @@ -124,5 +120,5 @@ when given a relative .Sh HISTORY The .Fn realpath -function call first appeared in +function first appeared in .Bx 4.4 . diff --git a/stdlib/FreeBSD/realpath.c b/stdlib/FreeBSD/realpath.c new file mode 100644 index 0000000..31e0977 --- /dev/null +++ b/stdlib/FreeBSD/realpath.c @@ -0,0 +1,197 @@ +/* + * 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 "un-namespace.h" + +/* + * 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 stat sb; + char *p, *q, *s; + size_t left_len, resolved_len; + unsigned symlinks; + int serrno, slen; + char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; + + 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 (getcwd(resolved, PATH_MAX) == NULL) { + 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); + } + + /* + * 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; + } + + /* + * 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 (lstat(resolved, &sb) != 0) { + if (errno == ENOENT && p == NULL) { + errno = serrno; + return (resolved); + } + return (NULL); + } + if (S_ISLNK(sb.st_mode)) { + 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; + } 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)); + } + } + + /* + * 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/FreeBSD/remque.c b/stdlib/FreeBSD/remque.c new file mode 100644 index 0000000..068a75f --- /dev/null +++ b/stdlib/FreeBSD/remque.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.c b/stdlib/FreeBSD/setenv.c similarity index 61% rename from stdlib/setenv.c rename to stdlib/FreeBSD/setenv.c index 6f9b315..d7c0394 100644 --- a/stdlib/setenv.c +++ b/stdlib/FreeBSD/setenv.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,14 +31,17 @@ * 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 - -char *__findenv __P((const char *, int *)); +char *__findenv(const char *, int *); /* * setenv -- @@ -71,14 +50,14 @@ char *__findenv __P((const char *, int *)); */ int setenv(name, value, rewrite) - register const char *name; - register const char *value; + const char *name; + const char *value; int rewrite; { - static int alloced; /* if allocated space before */ - register char *c; + extern char **environ; + static char **alloced; /* if allocated space before */ + char *c; int l_value, offset; - char ***environp = _NSGetEnviron(); if (*value == '=') /* no `=' in value */ ++value; @@ -87,37 +66,38 @@ setenv(name, value, rewrite) if (!rewrite) return (0); if (strlen(c) >= l_value) { /* old larger; copy over */ - while (*c++ = *value++); + while ( (*c++ = *value++) ); return (0); } } else { /* create new slot */ - register int cnt; - register char **p; + int cnt; + char **p; - for (p = *environp, cnt = 0; *p; ++p, ++cnt); - if (alloced) { /* just increase size */ - *environp = (char **)realloc((char *)*environp, + for (p = environ, cnt = 0; *p; ++p, ++cnt); + if (alloced == environ) { /* just increase size */ + p = (char **)realloc((char *)environ, (size_t)(sizeof(char *) * (cnt + 2))); - if (!*environp) + if (!p) return (-1); + alloced = environ = p; } else { /* get new space */ - alloced = 1; /* copy old entries into it */ + /* copy old entries into it */ p = malloc((size_t)(sizeof(char *) * (cnt + 2))); if (!p) return (-1); - bcopy(*environp, p, cnt * sizeof(char *)); - *environp = p; + bcopy(environ, p, cnt * sizeof(char *)); + alloced = environ = p; } - (*environp)[cnt + 1] = NULL; + environ[cnt + 1] = NULL; offset = cnt; } for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ - if (!((*environp)[offset] = /* name + `=' + value */ + if (!(environ[offset] = /* name + `=' + value */ malloc((size_t)((int)(c - name) + l_value + 2)))) return (-1); - for (c = (*environp)[offset]; (*c = *name++) && *c != '='; ++c); - for (*c++ = '='; *c++ = *value++;); + for (c = environ[offset]; (*c = *name++) && *c != '='; ++c); + for (*c++ = '='; (*c++ = *value++); ); return (0); } @@ -129,8 +109,8 @@ void unsetenv(name) const char *name; { - char **environ = *_NSGetEnviron(); - register char **p; + extern char **environ; + char **p; int offset; while (__findenv(name, &offset)) /* if set multiple times */ diff --git a/stdlib/FreeBSD/setenv.c.patch b/stdlib/FreeBSD/setenv.c.patch new file mode 100644 index 0000000..7893ccd --- /dev/null +++ b/stdlib/FreeBSD/setenv.c.patch @@ -0,0 +1,68 @@ +--- setenv.c.orig Mon Apr 28 16:37:26 2003 ++++ setenv.c Tue May 6 16:55:50 2003 +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + char *__findenv(const char *, int *); + +@@ -54,7 +55,7 @@ + const char *value; + int rewrite; + { +- extern char **environ; ++ char ***environp = _NSGetEnviron(); + static char **alloced; /* if allocated space before */ + char *c; + int l_value, offset; +@@ -73,30 +74,30 @@ + int cnt; + char **p; + +- for (p = environ, cnt = 0; *p; ++p, ++cnt); +- 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 */ ++ p = (char **)realloc((char *)*environp, + (size_t)(sizeof(char *) * (cnt + 2))); + if (!p) + return (-1); +- alloced = environ = p; ++ alloced = *environp = p; + } + else { /* get new space */ + /* copy old entries into it */ + p = malloc((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; + } +- environ[cnt + 1] = NULL; ++ (*environp)[cnt + 1] = NULL; + offset = cnt; + } + for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */ +- if (!(environ[offset] = /* name + `=' + value */ ++ if (!((*environp)[offset] = /* name + `=' + value */ + malloc((size_t)((int)(c - name) + l_value + 2)))) + return (-1); +- for (c = environ[offset]; (*c = *name++) && *c != '='; ++c); ++ for (c = (*environp)[offset]; (*c = *name++) && *c != '='; ++c); + for (*c++ = '='; (*c++ = *value++); ); + return (0); + } +@@ -109,7 +110,7 @@ + unsetenv(name) + const char *name; + { +- extern char **environ; ++ char **environ = *_NSGetEnviron(); + char **p; + int offset; + diff --git a/stdlib/strfmon.3 b/stdlib/FreeBSD/strfmon.3 similarity index 55% rename from stdlib/strfmon.3 rename to stdlib/FreeBSD/strfmon.3 index a01bd42..739a798 100644 --- a/stdlib/strfmon.3 +++ b/stdlib/FreeBSD/strfmon.3 @@ -22,9 +22,9 @@ .\" 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.3 2001/10/01 13:50:03 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strfmon.3,v 1.7 2003/01/06 06:21:25 tjr Exp $ .\" -.Dd September 7, 2001 +.Dd October 12, 2002 .Dt STRFMON 3 .Os .Sh NAME @@ -35,7 +35,7 @@ .Sh SYNOPSIS .In monetary.h .Ft ssize_t -.Fn strfmon "char *s" "size_t maxsize" "const char *format" "..." +.Fn strfmon "char * restrict s" "size_t maxsize" "const char * restrict format" "..." .Sh DESCRIPTION The .Fn strfmon @@ -46,6 +46,73 @@ as controlled by the string pointed to by No more than .Fa maxsize bytes are placed into the array. +.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 @@ -69,6 +136,10 @@ 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 @@ -77,9 +148,7 @@ The .Fn strfmon function conforms to -.St -xpg4 -and -.St -susv2 . +.St -p1003.1-2001 . .Sh AUTHORS .An -nosplit The @@ -90,3 +159,9 @@ function was implemented by 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/FreeBSD/strfmon.3.patch b/stdlib/FreeBSD/strfmon.3.patch new file mode 100644 index 0000000..d5cf0ca --- /dev/null +++ b/stdlib/FreeBSD/strfmon.3.patch @@ -0,0 +1,11 @@ +--- strfmon.3.orig Mon Apr 28 16:37:26 2003 ++++ strfmon.3 Sat May 3 01:09:16 2003 +@@ -35,7 +35,7 @@ + .Sh SYNOPSIS + .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" "..." + .Sh DESCRIPTION + The + .Fn strfmon diff --git a/stdlib/FreeBSD/strfmon.c b/stdlib/FreeBSD/strfmon.c new file mode 100644 index 0000000..db569d5 --- /dev/null +++ b/stdlib/FreeBSD/strfmon.c @@ -0,0 +1,603 @@ +/*- + * 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 +#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) do { \ + VAR = 0; \ + while (isdigit((unsigned char)*fmt)) { \ + 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 **); +static int __calc_left_pad(int, char *); +static char *__format_grouped_double(double, int *, int, int, int); + +ssize_t +strfmon(char * __restrict s, size_t maxsize, 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; + + va_start(ap, format); + + lc = localeconv(); + 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((unsigned char)*fmt)) { + GET_NUMBER(width); + /* 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((unsigned char)*++fmt)) + goto format_error; + GET_NUMBER(left_prec); + } + + /* Right precision */ + if (*fmt == '.') { + if (!isdigit((unsigned char)*++fmt)) + goto format_error; + GET_NUMBER(right_prec); + } + + /* 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); + } 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) - + __calc_left_pad(flags, currency_symbol); + if (pad_size < 0) + pad_size = 0; + } + + asciivalue = __format_grouped_double(value, &flags, + left_prec, right_prec, pad_char); + 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); + + /* + * 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); + + 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 && (flags & IS_NEGATIVE)) + 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'); + va_end(ap); + 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; + va_end(ap); + return (-1); +} + +static void +__setup_vars(int flags, char *cs_precedes, char *sep_by_space, + char *sign_posn, char **signstr) { + + struct lconv *lc = localeconv(); + + 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) { + + char cs_precedes, sep_by_space, sign_posn, *signstr; + int left_chars = 0; + + __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr); + + if (cs_precedes != 0) { + left_chars += strlen(cur_symb); + if (sep_by_space != 0) + left_chars++; + } + + switch (sign_posn) { + 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 */ +static char * +__format_grouped_double(double value, int *flags, + int left_prec, int right_prec, int pad_char) { + + char *rslt; + char *avalue; + int avalue_size; + char fmt[32]; + + size_t bufsize; + char *bufend; + + int padded; + + struct lconv *lc = localeconv(); + char *grouping; + char decimal_point; + char thousands_sep; + + int groups = 0; + + grouping = 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(fmt, sizeof(fmt), "%%%d.%df", left_prec + right_prec + 1, + right_prec); + avalue_size = asprintf(&avalue, 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); +} diff --git a/stdlib/FreeBSD/strhash.c b/stdlib/FreeBSD/strhash.c new file mode 100644 index 0000000..022c45b --- /dev/null +++ b/stdlib/FreeBSD/strhash.c @@ -0,0 +1,407 @@ +/* + * + * 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); + + +/* + * 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){ + + static int assign_key(); + + 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/FreeBSD/strtod.3 similarity index 51% rename from stdlib/strtod.3 rename to stdlib/FreeBSD/strtod.3 index 2aaa34f..52a0ac5 100644 --- a/stdlib/strtod.3 +++ b/stdlib/FreeBSD/strtod.3 @@ -34,39 +34,67 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtod.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtod.3,v 1.13 2001/09/07 14:46:36 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtod.3,v 1.18 2003/03/12 20:31:05 das Exp $ .\" -.Dd June 4, 1993 +.Dd March 2, 2003 .Dt STRTOD 3 .Os .Sh NAME -.Nm strtod +.Nm strtod , strtof , strtold .Nd convert .Tn ASCII -string to double +string to floating point .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .Ft double -.Fn strtod "const char *nptr" "char **endptr" +.Fn strtod "const char * restrict nptr" "char ** restrict endptr" +.Ft float +.Fn strtof "const char * restrict nptr" "char ** restrict endptr" +.Ft long double +.Fn strtold "const char * restrict nptr" "char ** restrict endptr" .Sh DESCRIPTION -The -.Fn strtod -function converts the initial portion of the string +These conversion +functions convert the initial portion of the string pointed to by .Fa nptr to -.Em double -representation. +.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 a sequence of digits optionally containing -a decimal-point character, optionally followed by an exponent. -An exponent consists of an ``E'' or ``e'', followed by an optional plus -or minus sign, followed by a sequence of digits. +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 -Leading white-space characters in the string (as defined by the +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 @@ -74,8 +102,11 @@ character is defined in the program's locale (category .Dv LC_NUMERIC ) . .Sh RETURN VALUES The -.Fn strtod -function returns the converted value, if any. +.Fn strtod , +.Fn strtof , +and +.Fn strtold +functions return the converted value, if any. .Pp If .Fa endptr @@ -91,8 +122,11 @@ is stored in the location referenced by .Fa endptr . .Pp If the correct value would cause overflow, plus or minus -.Dv HUGE_VAL -is returned (according to the sign of the value), and +.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 . @@ -111,30 +145,40 @@ Overflow or underflow occurred. .Xr atoi 3 , .Xr atol 3 , .Xr strtol 3 , -.Xr strtoul 3 +.Xr strtoul 3 , +.Xr wcstod 3 .Sh STANDARDS The .Fn strtod function conforms to -.St -isoC . +.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 -Copyright (c) 1991 by AT&T. +Copyright (c) 1998 by Lucent Technologies +.br +All Rights Reserved .Pp -Permission to use, copy, modify, and distribute this software for any -purpose without fee is hereby granted, provided that this entire notice -is included in all copies of any software which is or includes a copy -or modification of this software and in all copies of the supporting -documentation for such software. +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. .Pp -THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED -WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY -REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY -OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. -.Pp -Contact your vendor for a free copy of the source code to -.Fn strtod -and accompanying functions. +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. diff --git a/stdlib/FreeBSD/strtoimax.c b/stdlib/FreeBSD/strtoimax.c new file mode 100644 index 0000000..c57d044 --- /dev/null +++ b/stdlib/FreeBSD/strtoimax.c @@ -0,0 +1,141 @@ +/*- + * 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 +#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(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + const char *s; + uintmax_t acc; + char c; + uintmax_t cutoff; + int neg, any, cutlim; + + /* + * 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((unsigned char)c)); + 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); +} diff --git a/stdlib/strtol.3 b/stdlib/FreeBSD/strtol.3 similarity index 76% rename from stdlib/strtol.3 rename to stdlib/FreeBSD/strtol.3 index 0033f4e..9f54054 100644 --- a/stdlib/strtol.3 +++ b/stdlib/FreeBSD/strtol.3 @@ -34,23 +34,30 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtol.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.14 2001/09/11 09:39:23 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.19 2002/10/10 04:31:57 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd November 28, 2001 .Dt STRTOL 3 .Os .Sh NAME -.Nm strtol , strtoll , strtoq -.Nd "convert a string value to a long, long long, or quad_t integer" +.Nm strtol , strtoll , strtoimax , 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 stdlib.h .In limits.h .Ft long -.Fn strtol "const char *nptr" "char **endptr" "int base" +.Fn strtol "const char * restrict nptr" "char ** restrict endptr" "int base" .Ft long long -.Fn strtoll "const char *nptr" "char **endptr" "int base" +.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" .In sys/types.h .In stdlib.h .In limits.h @@ -63,7 +70,7 @@ function converts the string in .Fa nptr to a -.Em long +.Vt long value. The .Fn strtoll @@ -71,7 +78,15 @@ function converts the string in .Fa nptr to a -.Em long long +.Vt "long long" +value. +The +.Fn strtoimax +function +converts the string in +.Fa nptr +to an +.Vt intmax_t value. The .Fn strtoq @@ -79,7 +94,7 @@ function converts the string in .Fa nptr to a -.Em quad_t +.Vt quad_t value. The conversion is done according to the given .Fa base , @@ -98,7 +113,7 @@ If .Fa base is zero or 16, the string may then include a -.Ql 0x +.Dq Li 0x prefix, and the number will be read in base 16; otherwise, a zero .Fa base @@ -107,7 +122,9 @@ is taken as 10 (decimal) unless the next character is in which case it is taken as 8 (octal). .Pp The remainder of the string is converted to a -.Em long +.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. @@ -122,7 +139,8 @@ representing 35.) .Pp If .Fa endptr -is non nil, +is not +.Dv NULL , .Fn strtol stores the address of the first invalid character in .Fa *endptr . @@ -143,37 +161,32 @@ is on return, the entire string was valid.) .Sh RETURN VALUES The -.Fn strtol -or -.Fn strtoll -function -returns the result of the conversion, +.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 . -If an underflow occurs, -.Fn strtol -returns -.Dv LONG_MIN . -If an overflow occurs, -.Fn strtol -returns -.Dv LONG_MAX . -If an underflow occurs, -.Fn strtoll -returns -.Dv LLONG_MIN . -If an overflow occurs, -.Fn strtoll -returns -.Dv LLONG_MAX . -In all cases, +If an overflow or underflow occurs, .Va errno is set to -.Er ERANGE . +.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 +.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 @@ -189,7 +202,8 @@ The given string was out of range; the value converted has been clamped. .Xr atoi 3 , .Xr atol 3 , .Xr strtod 3 , -.Xr strtoul 3 +.Xr strtoul 3 , +.Xr wcstol 3 .Sh STANDARDS The .Fn strtol @@ -198,8 +212,10 @@ conforms to .St -isoC . The .Fn strtoll -function -conforms to +and +.Fn strtoimax +functions +conform to .St -isoC-99 . The .Bx diff --git a/stdlib/strtol.c b/stdlib/FreeBSD/strtol.c similarity index 65% rename from stdlib/strtol.c rename to stdlib/FreeBSD/strtol.c index 75b851e..2b3fcf4 100644 --- a/stdlib/strtol.c +++ b/stdlib/FreeBSD/strtol.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 #include @@ -65,34 +46,35 @@ /* * Convert a string to a long integer. * - * Ignores `locale' stuff. Assumes that the upper and lower case + * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long -strtol(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; +strtol(const char * __restrict nptr, char ** __restrict endptr, int base) { - register const char *s = nptr; - register unsigned long acc; - register int c; - register unsigned long cutoff; - register int neg = 0, any, cutlim; + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; /* * 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(c)); + } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; - } else if (c == '+') - c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; @@ -101,6 +83,9 @@ strtol(nptr, endptr, base) } 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 @@ -116,22 +101,25 @@ strtol(nptr, endptr, base) * 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 + * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ - cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; - cutlim = cutoff % (unsigned long)base; - cutoff /= (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) + 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 (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + 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) + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; @@ -142,9 +130,12 @@ strtol(nptr, endptr, base) if (any < 0) { acc = neg ? LONG_MIN : LONG_MAX; errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; } else if (neg) acc = -acc; - if (endptr != 0) + if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/strtoll.c b/stdlib/FreeBSD/strtoll.c similarity index 82% rename from stdlib/strtoll.c rename to stdlib/FreeBSD/strtoll.c index 41a16c6..cff57d9 100644 --- a/stdlib/strtoll.c +++ b/stdlib/FreeBSD/strtoll.c @@ -34,13 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; -#endif - -#include +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp $"); #include #include @@ -50,20 +45,17 @@ static const char rcsid[] = /* * Convert a string to a long long integer. * - * Ignores `locale' stuff. Assumes that the upper and lower case + * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long long -strtoll(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; +strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) { - register const char *s; - register unsigned long long acc; - register unsigned char c; - register unsigned long long qbase, cutoff; - register int neg, any, cutlim; + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; /* * Skip white space and pick up leading +/- sign if any. @@ -73,7 +65,7 @@ strtoll(nptr, endptr, base) s = nptr; do { c = *s++; - } while (isspace(c)); + } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; @@ -90,6 +82,9 @@ strtoll(nptr, endptr, base) } 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 @@ -106,21 +101,20 @@ strtoll(nptr, endptr, base) * 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 + * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ - qbase = (unsigned)base; cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX : LLONG_MAX; - cutlim = cutoff % qbase; - cutoff /= qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; else break; if (c >= base) @@ -129,16 +123,19 @@ strtoll(nptr, endptr, base) any = -1; else { any = 1; - acc *= qbase; + 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 != 0) + if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/strtoq.c b/stdlib/FreeBSD/strtoq.c similarity index 85% rename from stdlib/strtoq.c rename to stdlib/FreeBSD/strtoq.c index dcda96a..6e8bcb8 100644 --- a/stdlib/strtoq.c +++ b/stdlib/FreeBSD/strtoq.c @@ -34,11 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.4.6.1 2001/03/02 09:45:20 obrien Exp $"; -#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); #include @@ -46,15 +43,9 @@ static const char rcsid[] = /* * Convert a string to a quad integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. */ quad_t -strtoq(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; +strtoq(const char *nptr, char **endptr, int base) { return strtoll(nptr, endptr, base); diff --git a/stdlib/strtoul.3 b/stdlib/FreeBSD/strtoul.3 similarity index 81% rename from stdlib/strtoul.3 rename to stdlib/FreeBSD/strtoul.3 index 2bc473e..48bf05c 100644 --- a/stdlib/strtoul.3 +++ b/stdlib/FreeBSD/strtoul.3 @@ -34,23 +34,30 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtoul.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.14 2001/09/11 09:39:23 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.20 2002/10/10 04:31:57 tjr Exp $ .\" -.Dd June 4, 1993 +.Dd November 28, 2001 .Dt STRTOUL 3 .Os .Sh NAME -.Nm strtoul , strtoull , strtouq -.Nd "convert a string to an unsigned long, unsigned long long, or uquad_t integer" +.Nm strtoul , strtoull , strtoumax , 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 .In limits.h -.Ft unsigned long -.Fn strtoul "const char *nptr" "char **endptr" "int base" -.Ft unsigned long long -.Fn strtoull "const char *nptr" "char **endptr" "int base" +.Ft "unsigned long" +.Fn strtoul "const char * restrict nptr" "char ** restrict endptr" "int base" +.Ft "unsigned long long" +.Fn strtoull "const char * restrict nptr" "char ** restrict endptr" "int base" +.In inttypes.h +.Ft uintmax_t +.Fn strtoumax "const char * restrict nptr" "char ** restrict endptr" "int base" .In sys/types.h .In stdlib.h .In limits.h @@ -63,7 +70,7 @@ function converts the string in .Fa nptr to an -.Em unsigned long +.Vt "unsigned long" value. The .Fn strtoull @@ -71,7 +78,15 @@ function converts the string in .Fa nptr to an -.Em unsigned long long +.Vt "unsigned long long" +value. +The +.Fn strtoumax +function +converts the string in +.Fa nptr +to an +.Vt uintmax_t value. The .Fn strtouq @@ -79,7 +94,7 @@ function converts the string in .Fa nptr to a -.Em u_quad_t +.Vt u_quad_t value. The conversion is done according to the given .Fa base , @@ -98,7 +113,7 @@ If .Fa base is zero or 16, the string may then include a -.Ql 0x +.Dq Li 0x prefix, and the number will be read in base 16; otherwise, a zero .Fa base @@ -107,7 +122,7 @@ is taken as 10 (decimal) unless the next character is in which case it is taken as 8 (octal). .Pp The remainder of the string is converted to an -.Em unsigned long +.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 @@ -123,7 +138,8 @@ representing 35.) .Pp If .Fa endptr -is non nil, +is not +.Dv NULL , .Fn strtoul stores the address of the first invalid character in .Fa *endptr . @@ -144,21 +160,29 @@ is on return, the entire string was valid.) .Sh RETURN VALUES The -.Fn strtoul -or -.Fn strtoull -function -returns either the result of the conversion +.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 -and +.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 @@ -180,7 +204,8 @@ no conversion could be performed. The given string was out of range; the value converted has been clamped. .El .Sh SEE ALSO -.Xr strtol 3 +.Xr strtol 3 , +.Xr wcstoul 3 .Sh STANDARDS The .Fn strtoul @@ -189,10 +214,12 @@ conforms to .St -isoC . The .Fn strtoull -function -conforms to +and +.Fn strtoumax +functions +conform to .St -isoC-99 . The .Bx -.Fn strtoq +.Fn strtouq function is deprecated. diff --git a/stdlib/strtoul.c b/stdlib/FreeBSD/strtoul.c similarity index 59% rename from stdlib/strtoul.c rename to stdlib/FreeBSD/strtoul.c index 7e5ffb7..40eeba3 100644 --- a/stdlib/strtoul.c +++ b/stdlib/FreeBSD/strtoul.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,6 +31,11 @@ * 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 #include @@ -64,32 +45,33 @@ /* * Convert a string to an unsigned long integer. * - * Ignores `locale' stuff. Assumes that the upper and lower case + * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long -strtoul(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; +strtoul(const char * __restrict nptr, char ** __restrict endptr, int base) { - register const char *s = nptr; - register unsigned long acc; - register int c; - register unsigned long cutoff; - register int neg = 0, any, cutlim; + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; /* * See strtol for comments as to the logic used. */ + s = nptr; do { c = *s++; - } while (isspace(c)); + } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; - } else if (c == '+') - c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; @@ -98,18 +80,24 @@ strtoul(nptr, endptr, base) } if (base == 0) base = c == '0' ? 8 : 10; - cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; - cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) + 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 (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + 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) + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; @@ -120,9 +108,12 @@ strtoul(nptr, endptr, base) if (any < 0) { acc = ULONG_MAX; errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; } else if (neg) acc = -acc; - if (endptr != 0) + if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/strtoull.c b/stdlib/FreeBSD/strtoull.c similarity index 77% rename from stdlib/strtoull.c rename to stdlib/FreeBSD/strtoull.c index f80850e..43f3138 100644 --- a/stdlib/strtoull.c +++ b/stdlib/FreeBSD/strtoull.c @@ -34,13 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; -#endif - -#include +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp $"); #include #include @@ -50,20 +45,17 @@ static const char rcsid[] = /* * Convert a string to an unsigned long long integer. * - * Ignores `locale' stuff. Assumes that the upper and lower case + * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long long -strtoull(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; +strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) { - register const char *s = nptr; - register unsigned long long acc; - register unsigned char c; - register unsigned long long qbase, cutoff; - register int neg, any, cutlim; + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; /* * See strtoq for comments as to the logic used. @@ -71,7 +63,7 @@ strtoull(nptr, endptr, base) s = nptr; do { c = *s++; - } while (isspace(c)); + } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; @@ -88,16 +80,19 @@ strtoull(nptr, endptr, base) } if (base == 0) base = c == '0' ? 8 : 10; - qbase = (unsigned)base; - cutoff = (unsigned long long)ULLONG_MAX / qbase; - cutlim = (unsigned long long)ULLONG_MAX % qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) + 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 (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; else break; if (c >= base) @@ -106,16 +101,19 @@ strtoull(nptr, endptr, base) any = -1; else { any = 1; - acc *= qbase; + 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 != 0) + if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } diff --git a/stdlib/FreeBSD/strtoumax.c b/stdlib/FreeBSD/strtoumax.c new file mode 100644 index 0000000..eb714d7 --- /dev/null +++ b/stdlib/FreeBSD/strtoumax.c @@ -0,0 +1,119 @@ +/*- + * 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 +#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(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + const char *s; + uintmax_t acc; + char c; + uintmax_t cutoff; + int neg, any, cutlim; + + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + 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); +} diff --git a/stdlib/strtouq.c b/stdlib/FreeBSD/strtouq.c similarity index 85% rename from stdlib/strtouq.c rename to stdlib/FreeBSD/strtouq.c index 89f26d8..c0e0bef 100644 --- a/stdlib/strtouq.c +++ b/stdlib/FreeBSD/strtouq.c @@ -34,11 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.4.8.1 2001/03/02 09:45:20 obrien Exp $"; -#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.11 2002/08/15 09:25:04 robert Exp $"); #include @@ -46,15 +43,9 @@ static const char rcsid[] = /* * Convert a string to an unsigned quad integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. */ u_quad_t -strtouq(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; +strtouq(const char *nptr, char **endptr, int base) { return strtoull(nptr, endptr, base); diff --git a/stdlib/system.3 b/stdlib/FreeBSD/system.3 similarity index 96% rename from stdlib/system.3 rename to stdlib/FreeBSD/system.3 index a6aa661..f0557c8 100644 --- a/stdlib/system.3 +++ b/stdlib/FreeBSD/system.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)system.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.10 2001/09/07 14:46:36 asmodai Exp $ +.\" $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 @@ -97,7 +97,7 @@ The .Fn system function conforms to -.St -isoC . +.St -isoC and is expected to be .St -p1003.2 compatible. diff --git a/stdlib/system.c b/stdlib/FreeBSD/system.c similarity index 57% rename from stdlib/system.c rename to stdlib/FreeBSD/system.c index fbe8a53..fd2cc2a 100644 --- a/stdlib/system.c +++ b/stdlib/FreeBSD/system.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,7 +31,13 @@ * 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 @@ -64,37 +46,57 @@ #include #include #include +#include "un-namespace.h" +#include "libc_private.h" -system(command) +int +__system(command) const char *command; { - union wait pstat; - pid_t kid, pid; - int omask; - sig_t intsave, quitsave; + pid_t pid, savedpid; + int pstat; + struct sigaction ign, intact, quitact; + sigset_t newsigblock, oldsigblock; if (!command) /* just checking... */ return(1); - omask = sigblock(sigmask(SIGCHLD)); - switch(kid = vfork()) { + /* + * 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 */ - (void)sigsetmask(omask); - pstat.w_status = 0; - pstat.w_retcode = 127; - return(pstat.w_status); + break; case 0: /* child */ - (void)sigsetmask(omask); + /* + * Restore original signal dispositions and exec the command. + */ + (void)_sigaction(SIGINT, &intact, NULL); + (void)_sigaction(SIGQUIT, &quitact, NULL); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); 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; } - intsave = signal(SIGINT, SIG_IGN); - quitsave = signal(SIGQUIT, SIG_IGN); - do { - pid = waitpid(kid, (int *)&pstat, 0); - } while (pid < 0 && errno == EINTR); - (void)sigsetmask(omask); - (void)signal(SIGINT, intsave); - (void)signal(SIGQUIT, quitsave); - return(pid == -1 ? -1 : pstat.w_status); + (void)_sigaction(SIGINT, &intact, NULL); + (void)_sigaction(SIGQUIT, &quitact, NULL); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + return(pid == -1 ? -1 : pstat); } + +__weak_reference(__system, system); +__weak_reference(__system, _system); diff --git a/stdlib/FreeBSD/tdelete.c b/stdlib/FreeBSD/tdelete.c new file mode 100644 index 0000000..7fb6893 --- /dev/null +++ b/stdlib/FreeBSD/tdelete.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/FreeBSD/tfind.c b/stdlib/FreeBSD/tfind.c new file mode 100644 index 0000000..b58ed88 --- /dev/null +++ b/stdlib/FreeBSD/tfind.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.3 b/stdlib/FreeBSD/tsearch.3 similarity index 89% rename from stdlib/tsearch.3 rename to stdlib/FreeBSD/tsearch.3 index a36fe89..6c5ee0e 100644 --- a/stdlib/tsearch.3 +++ b/stdlib/FreeBSD/tsearch.3 @@ -25,7 +25,7 @@ .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp -.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.7 2001/09/07 14:46:36 asmodai Exp $ +.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.12 2002/12/19 09:40:24 ru Exp $ .\" .Dd June 15, 1997 .Dt TSEARCH 3 @@ -36,9 +36,9 @@ .Sh SYNOPSIS .In search.h .Ft void * -.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" +.Fn tdelete "const void * restrict key" "void ** restrict rootp" "int (*compar) (const void *, const void *)" .Ft void * -.Fn tfind "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" +.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)" .Ft void * .Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" .Ft void @@ -55,7 +55,9 @@ from Knuth (6.2.2). The comparison function passed in by the user has the same style of return values as .Xr strcmp 3 . .Pp -.Fn Tfind +The +.Fn tfind +function searches for the datum matched by the argument .Fa key in the binary tree rooted at @@ -63,7 +65,9 @@ in the binary tree rooted at returning a pointer to the datum if it is found and NULL if it is not. .Pp -.Fn Tsearch +The +.Fn tsearch +function is identical to .Fn tfind except that if no match is found, @@ -72,7 +76,9 @@ is inserted into the tree and a pointer to it is returned. If .Fa rootp points to a NULL value a new binary search tree is created. .Pp -.Fn Tdelete +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. It takes the same arguments as @@ -83,13 +89,17 @@ If the node to be deleted is the root of the binary search tree, .Fa rootp will be adjusted. .Pp -.Fn Twalk +The +.Fn twalk +function walks the binary search tree rooted in .Fa root and calls the function .Fa action on each node. -.Fa Action +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;" @@ -105,10 +115,12 @@ The function returns NULL if allocation of a new node fails (usually due to a lack of free memory). .Pp -.Fn Tfind , +The +.Fn tfind , .Fn tsearch , and .Fn tdelete +functions return NULL if .Fa rootp is NULL or the datum cannot be found. diff --git a/stdlib/FreeBSD/tsearch.c b/stdlib/FreeBSD/tsearch.c new file mode 100644 index 0000000..edeccde --- /dev/null +++ b/stdlib/FreeBSD/tsearch.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/FreeBSD/twalk.c b/stdlib/FreeBSD/twalk.c new file mode 100644 index 0000000..516ef44 --- /dev/null +++ b/stdlib/FreeBSD/twalk.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/stdlib/Makefile.inc b/stdlib/Makefile.inc index 2ed34f1..a9aa664 100644 --- a/stdlib/Makefile.inc +++ b/stdlib/Makefile.inc @@ -1,24 +1,22 @@ # from @(#)Makefile.inc 8.3 (Berkeley) 2/4/95 -# $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.32 2001/09/07 13:03:16 phantom Exp $ +# $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.45 2003/04/05 07:33:46 tjr Exp $ # machine-independent stdlib sources .PATH: ${.CURDIR}/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib -MISRCS+=abort.c bsearch.c getsubopt.c putenv.c setenv.c strtouq.c \ - atexit.c div.c heapsort.c qsort.c strtod.c system.c \ - atof.c exit.c labs.c radixsort.c strtol.c \ - atoi.c getenv.c ldiv.c rand.c strtoq.c \ - atol.c getopt.c merge.c random.c strtoul.c \ - reallocf.c a64l.c l64a.c strtoll.c strtoull.c +MISRCS+=a64l.c l64a.c -.if ${MACHINE_ARCH} == "alpha" -# XXX Temporary until the assumption that a long is 32-bits is resolved -# XXX FreeBSD's code. NetBSD kludged this with Long = int32_t and -# XXX ULong = u_int32_t -SRCS+= netbsd_strtod.c -.else -SRCS+= strtod.c -.endif +.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 \ + 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 \ + strtoull.c strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c \ + twalk.c +FBSDORIGHDRS= atexit.h +.include "Makefile.fbsd_end" # machine-dependent stdlib sources .if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc) @@ -26,20 +24,29 @@ SRCS+= strtod.c .endif .if ${LIB} == "c" -MAN3+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ - div.3 exit.3 getenv.3 getopt.3 getsubopt.3 hcreate.3 labs.3 \ - ldiv.3 malloc.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 \ - a64l.3 +MAN3+= a64l.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 \ + 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 +.include "Makefile.fbsd_end" +MLINKS+=a64l.3 l64a.3 +MLINKS+=atol.3 atoll.3 +MLINKS+=exit.3 _Exit.3 MLINKS+=getenv.3 putenv.3 getenv.3 setenv.3 getenv.3 unsetenv.3 MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3 -MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.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+=strtol.3 strtoll.3 strtol.3 strtoq.3 -MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 -MLINKS+=malloc.3 calloc.3 malloc.3 free.3 malloc.3 realloc.3 malloc.3 reallocf.3 -MLINKS+=tsearch.3 tdelete.3 tsearch.3 tfind.3 tsearch.3 twalk.3 a64l.3 l64a.3 +MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3 +MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.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 .endif diff --git a/stdlib/a64l.c b/stdlib/a64l.c index 67415b4..53d671f 100644 --- a/stdlib/a64l.c +++ b/stdlib/a64l.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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. diff --git a/stdlib/abort.c b/stdlib/abort.c deleted file mode 100644 index 2bdf057..0000000 --- a/stdlib/abort.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include -#include -#include -#include - -void -abort() -{ - int mypid = getpid(); - volatile long i; - volatile long *excp = 0; - sigset_t mask; - - sigfillset(&mask); - /* - * don't block SIGABRT to give any handler a chance; we ignore - * any errors -- X3J11 doesn't allow abort to return anyway. - */ - sigdelset(&mask, SIGABRT); - (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); - (void)kill(mypid, SIGABRT); - - /* - * if SIGABRT ignored, or caught and the handler returns, do - * it again, only harder. - */ - (void)signal(SIGABRT, SIG_DFL); - (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); - (void)kill(mypid, SIGABRT); - - i = *excp; /* still no joy; cause a processor trap */ - i = *++excp; /* maybe an unaligned address will do it */ - - /* okay, let's try to write text space */ - excp = (volatile long *)&abort; - *excp = ~*excp; - *excp = ~*excp; - - i /= 0; /* this time for sure! */ - - /* increasing desperation; try signals until one of them sticks */ - (void)kill(mypid, SIGILL); - (void)kill(mypid, SIGBUS); - - /* almost last resort */ - _exit(1); - - /* if _exit returns, do not return */ - for (;;) - sleep(600); -} diff --git a/stdlib/l64a.c b/stdlib/l64a.c index c666bc6..93d50ff 100644 --- a/stdlib/l64a.c +++ b/stdlib/l64a.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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. diff --git a/stdlib/malloc.3 b/stdlib/malloc.3 deleted file mode 100644 index 76af046..0000000 --- a/stdlib/malloc.3 +++ /dev/null @@ -1,483 +0,0 @@ -.\" 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. -.\" -.\" @(#)malloc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/malloc.3,v 1.49 2001/11/05 00:39:27 dd Exp $ -.\" -.Dd August 27, 1996 -.Dt MALLOC 3 -.Os -.Sh NAME -.Nm malloc , calloc , realloc , free , reallocf -.Nd general purpose memory allocation functions -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdlib.h -.Ft void * -.Fn malloc "size_t size" -.Ft void * -.Fn calloc "size_t number" "size_t size" -.Ft void * -.Fn realloc "void *ptr" "size_t size" -.Ft void * -.Fn reallocf "void *ptr" "size_t size" -.Ft void -.Fn free "void *ptr" -.Ft char * -.Va _malloc_options -.Ft void -.Fn \*(lp*_malloc_message\*(rp "char *p1" "char *p2" "char *p3" "char *p4" -.Sh DESCRIPTION -The -.Fn malloc -function allocates -.Fa size -bytes of memory. -The allocated space is suitably aligned (after possible pointer coercion) -for storage of any type of object. -If the space is at least -.Em pagesize -bytes in length (see -.Xr getpagesize 3 ) , -the returned memory will be page boundary aligned as well. -If -.Fn malloc -fails, a -.Dv NULL -pointer is returned. -.Pp -Note that -.Fn malloc -does -.Em NOT -normally initialize the returned memory to zero bytes. -.Pp -The -.Fn calloc -function allocates space for -.Fa number -objects, -each -.Fa size -bytes in length. -The result is identical to calling -.Fn malloc -with an argument of -.Dq "number * size" , -with the exception that the allocated memory is explicitly initialized -to zero bytes. -.Pp -The -.Fn realloc -function changes the size of the previously allocated memory referenced by -.Fa ptr -to -.Fa size -bytes. -The contents of the memory are unchanged up to the lesser of the new and -old sizes. -If the new size is larger, -the value of the newly allocated portion of the memory is undefined. -If the requested memory cannot be allocated, -.Dv NULL -is returned and -the memory referenced by -.Fa ptr -is valid and unchanged. -If -.Fa ptr -is -.Dv NULL , -the -.Fn realloc -function behaves identically to -.Fn malloc -for the specified size. -.Pp -The -.Fn reallocf -function call is identical to the realloc function call, except that it -will free the passed pointer when the requested memory cannot be allocated. -This is a -.Fx -specific API designed to ease the problems with traditional coding styles -for realloc causing memory leaks in libraries. -.Pp -The -.Fn free -function causes the allocated memory referenced by -.Fa ptr -to be made available for future allocations. -If -.Fa ptr -is -.Dv NULL , -no action occurs. -.Sh TUNING -Once, when the first call is made to one of these memory allocation -routines, various flags will be set or reset, which affect the -workings of this allocation implementation. -.Pp -The ``name'' of the file referenced by the symbolic link named -.Pa /etc/malloc.conf , -the value of the environment variable -.Ev MALLOC_OPTIONS , -and the string pointed to by the global variable -.Va _malloc_options -will be interpreted, in that order, character by character as flags. -.Pp -Most flags are single letters, -where uppercase indicates that the behavior is set, or on, -and lowercase means that the behavior is not set, or off. -.Bl -tag -width indent -.It A -All warnings (except for the warning about unknown -flags being set) become fatal. -The process will call -.Xr abort 3 -in these cases. -.It J -Each byte of new memory allocated by -.Fn malloc , -.Fn realloc -or -.Fn reallocf -as well as all memory returned by -.Fn free , -.Fn realloc -or -.Fn reallocf -will be initialized to 0xd0. -This options also sets the -.Dq R -option. -This is intended for debugging and will impact performance negatively. -.It H -Pass a hint to the kernel about pages unused by the allocation functions. -This will help performance if the system is paging excessively. This -option is off by default. -.It R -Causes the -.Fn realloc -and -.Fn reallocf -functions to always reallocate memory even if the initial allocation was -sufficiently large. -This can substantially aid in compacting memory. -.It U -Generate -.Dq utrace -entries for -.Xr ktrace 1 , -for all operations. -Consult the source for details on this option. -.It V -Attempting to allocate zero bytes will return a -.Dv NULL -pointer instead of -a valid pointer. -(The default behavior is to make a minimal allocation and return a -pointer to it.) -This option is provided for System V compatibility. -This option is incompatible with the -.Dq X -option. -.It X -Rather than return failure for any allocation function, -display a diagnostic message on stderr and cause the program to drop -core (using -.Xr abort 3 ) . -This option should be set at compile time by including the following in -the source code: -.Bd -literal -offset indent -_malloc_options = "X"; -.Ed -.It Z -This option implicitly sets the -.Dq J -and -.Dq R -options, and then zeros out the bytes that were requested. -This is intended for debugging and will impact performance negatively. -.It < -Reduce the size of the cache by a factor of two. -The default cache size is 16 pages. -This option can be specified multiple times. -.It > -Double the size of the cache by a factor of two. -The default cache size is 16 pages. -This option can be specified multiple times. -.El -.Pp -The -.Dq J -and -.Dq Z -options are intended for testing and debugging. -An application which changes its behavior when these options are used -is flawed. -.Sh EXAMPLES -To set a systemwide reduction of cache size, and to dump core whenever -a problem occurs: -.Pp -.Bd -literal -offset indent -ln -s 'A<' /etc/malloc.conf -.Ed -.Pp -To specify in the source that a program does no return value checking -on calls to these functions: -.Bd -literal -offset indent -_malloc_options = "X"; -.Ed -.Sh ENVIRONMENT -The following environment variables affect the execution of the allocation -functions: -.Bl -tag -width ".Ev MALLOC_OPTIONS" -.It Ev MALLOC_OPTIONS -If the environment variable -.Ev MALLOC_OPTIONS -is set, the characters it contains will be interpreted as flags to the -allocation functions. -.El -.Sh RETURN VALUES -The -.Fn malloc -and -.Fn calloc -functions return a pointer to the allocated memory if successful; otherwise -a -.Dv NULL -pointer is returned and -.Va errno -is set to -.Er ENOMEM . -.Pp -The -.Fn realloc -and -.Fn reallocf -functions return a pointer, possibly identical to -.Fa ptr , -to the allocated memory -if successful; otherwise a -.Dv NULL -pointer is returned, in which case the -memory referenced by -.Fa ptr -is still available and intact. -In the case of memory allocation failure, -.Va errno -is set to -.Er ENOMEM . -.Pp -The -.Fn free -function returns no value. -.Sh DEBUGGING MALLOC PROBLEMS -The major difference between this implementation and other allocation -implementations is that the free pages are not accessed unless allocated, -and are aggressively returned to the kernel for reuse. -.Bd -ragged -offset indent -Most allocation implementations will store a data structure containing a -linked list in the free chunks of memory, -used to tie all the free memory together. -That can be suboptimal, -as every time the free-list is traversed, -the otherwise unused, and likely paged out, -pages are faulted into primary memory. -On systems which are paging, -this can result in a factor of five increase in the number of page-faults -done by a process. -.Ed -.Pp -A side effect of this architecture is that many minor transgressions on -the interface which would traditionally not be detected are in fact -detected. As a result, programs that have been running happily for -years may suddenly start to complain loudly, when linked with this -allocation implementation. -.Pp -The first and most important thing to do is to set the -.Dq A -option. -This option forces a coredump (if possible) at the first sign of trouble, -rather than the normal policy of trying to continue if at all possible. -.Pp -It is probably also a good idea to recompile the program with suitable -options and symbols for debugger support. -.Pp -If the program starts to give unusual results, coredump or generally behave -differently without emitting any of the messages listed in the next -section, it is likely because it depends on the storage being filled with -zero bytes. Try running it with -.Dq Z -option set; -if that improves the situation, this diagnosis has been confirmed. -If the program still misbehaves, -the likely problem is accessing memory outside the allocated area, -more likely after than before the allocated area. -.Pp -Alternatively, if the symptoms are not easy to reproduce, setting the -.Dq J -option may help provoke the problem. -.Pp -In truly difficult cases, the -.Dq U -option, if supported by the kernel, can provide a detailed trace of -all calls made to these functions. -.Pp -Unfortunately this implementation does not provide much detail about -the problems it detects, the performance impact for storing such information -would be prohibitive. -There are a number of allocation implementations available on the 'Net -which focus on detecting and pinpointing problems by trading performance -for extra sanity checks and detailed diagnostics. -.Sh DIAGNOSTIC MESSAGES -If -.Fn malloc , -.Fn calloc , -.Fn realloc -or -.Fn free -detect an error or warning condition, -a message will be printed to file descriptor STDERR_FILENO. -Errors will result in the process dumping core. -If the -.Dq A -option is set, all warnings are treated as errors. -.Pp -The -.Va _malloc_message -variable allows the programmer to override the function which emits -the text strings forming the errors and warnings if for some reason -the stderr filedescriptor is not suitable for this. -Please note that doing anything which tries to allocate memory in -this function will assure death of the process. -.Pp -The following is a brief description of possible error messages and -their meanings: -.Pp -.Bl -diag -.It "(ES): mumble mumble mumble" -The allocation functions were compiled with -.Dq EXTRA_SANITY -defined, and an error was found during the additional error checking. -Consult the source code for further information. -.It "mmap(2) failed, check limits" -This most likely means that the system is dangerously overloaded or that -the process' limits are incorrectly specified. -.It "freelist is destroyed" -The internal free-list has been corrupted. -.It "out of memory" -The -.Dq X -option was specified and an allocation of memory failed. -.El -.Pp -The following is a brief description of possible warning messages and -their meanings: -.Bl -diag -.It "chunk/page is already free" -The process attempted to -.Fn free -memory which had already been freed. -.It "junk pointer, ..." -A pointer specified to one of the allocation functions points outside the -bounds of the memory of which they are aware. -.It "malloc() has never been called" -No memory has been allocated, -yet something is being freed or -realloc'ed. -.It "modified (chunk-/page-) pointer" -The pointer passed to -.Fn free -or -.Fn realloc -has been modified. -.It "pointer to wrong page" -The pointer that -.Fn free , -.Fn realloc , -or -.Fn reallocf -is trying to free does not reference a possible page. -.It "recursive call" -A process has attempted to call an allocation function recursively. -This is not permitted. In particular, signal handlers should not -attempt to allocate memory. -.It "unknown char in MALLOC_OPTIONS" -An unknown option was specified. -Even with the -.Dq A -option set, this warning is still only a warning. -.El -.Sh SEE ALSO -.Xr brk 2 , -.Xr mmap 2 , -.Xr alloca 3 , -.Xr getpagesize 3 , -.Xr memory 3 -.Pa /usr/share/doc/papers/malloc.ascii.gz -.Sh STANDARDS -The -.Fn malloc , -.Fn calloc , -.Fn realloc -and -.Fn free -functions conform to -.St -isoC . -.Sh HISTORY -The present allocation implementation started out as a filesystem for a -drum attached to a 20bit binary challenged computer which was built -with discrete germanium transistors. It has since graduated to -handle primary storage rather than secondary. -It first appeared in its new shape and ability in -.Fx 2.2 . -.Pp -The -.Xr reallocf 3 -function first appeared in -.Fx 3.0 . -.Sh AUTHORS -.An Poul-Henning Kamp Aq phk@FreeBSD.org -.Sh BUGS -The messages printed in case of problems provide no detail about the -actual values. -.Pp -It can be argued that returning a -.Dv NULL -pointer when asked to -allocate zero bytes is a silly response to a silly question. diff --git a/stdlib/strtod.c b/stdlib/strtod.c deleted file mode 100644 index 02caafe..0000000 --- a/stdlib/strtod.c +++ /dev/null @@ -1,2518 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991 by AT&T. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to - David M. Gay - AT&T Bell Laboratories, Room 2C-463 - 600 Mountain Avenue - Murray Hill, NJ 07974-2070 - U.S.A. - dmg@research.att.com or research!dmg - */ - -/* 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. 92-101]. - * - * 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_LITTLE_ENDIAN for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_BIG_ENDIAN 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. - * #define Unsigned_Shifts if >> does treats its left operand as unsigned. - * #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 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. - * #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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strtod.c,v 1.9 1997/03/25 17:07:30 rahnds Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ - defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ - defined(__powerpc__) || defined(__m88k__) || defined(__ppc__) -#include -#if BYTE_ORDER == BIG_ENDIAN -#define IEEE_BIG_ENDIAN -#else -#define IEEE_LITTLE_ENDIAN -#endif -#endif - -#ifdef __arm32__ -/* - * Although the CPU is little endian the FP has different - * byte and word endianness. The byte order is still little endian - * but the word order is big endian. - */ -#define IEEE_BIG_ENDIAN -#endif - -#ifdef vax -#define VAX -#endif - -#define Long int32_t -#define ULong u_int32_t - -#ifdef DEBUG -#include "stdio.h" -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#ifdef __cplusplus -#include "malloc.h" -#include "memory.h" -#else -#ifndef KR_headers -#include "stdlib.h" -#include "string.h" -#include "locale.h" -#else -#include "malloc.h" -#include "memory.h" -#endif -#endif - -#ifdef MALLOC -#ifdef KR_headers -extern char *MALLOC(); -#else -extern void *MALLOC(size_t); -#endif -#else -#define MALLOC malloc -#endif - -#include "ctype.h" -#include "errno.h" - -#if defined(__APPLE__) -/* - * Temporarily define this, so we avoid pulling in symbols from libm - */ -#define Bad_float_h -#endif - -#ifdef Bad_float_h -#undef __STDC__ -#ifdef IEEE_BIG_ENDIAN -#define IEEE_ARITHMETIC -#endif -#ifdef IEEE_LITTLE_ENDIAN -#define IEEE_ARITHMETIC -#endif - -#ifdef IEEE_ARITHMETIC -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#define FLT_ROUNDS 1 -#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 FLT_ROUNDS 0 -#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 FLT_ROUNDS 1 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif -#else -#include "float.h" -#endif -#ifndef __MATH_H__ -#include "math.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CONST -#ifdef KR_headers -#define CONST /* blank */ -#else -#define CONST const -#endif -#endif - -#ifdef Unsigned_Shifts -#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; -#else -#define Sign_Extend(a,b) /*no-op*/ -#endif - -#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ - defined(IBM) != 1 -Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or -IBM should be defined. -#endif - -#ifdef IEEE_LITTLE_ENDIAN -#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 - -/* 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_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__) -#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) */ - -#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) -#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 IEEE_Arith -#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 -#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ -#else -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#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 */ -#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 -#endif - -#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 - -#ifndef Just_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. - */ -#ifndef Pack_32 -#define Pack_32 -#endif -#endif - -#define Kmax 15 - -#ifdef __cplusplus -extern "C" double strtod(const char *s00, char **se); -extern "C" char *__dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve, char **resultp); -#endif - - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; - - typedef struct Bigint Bigint; - - static Bigint * -Balloc -#ifdef KR_headers - (k) int k; -#else - (int k) -#endif -{ - int x; - Bigint *rv; - - x = 1 << k; - rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(Long)); - rv->k = k; - rv->maxwds = x; - rv->sign = rv->wds = 0; - return rv; -} - - static void -Bfree -#ifdef KR_headers - (v) Bigint *v; -#else - (Bigint *v) -#endif -{ - free(v); -} - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - - static 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; - ULong *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - do { -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + a; - z = (xi >> 16) * m + (y >> 16); - a = (int)(z >> 16); - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + a; - a = (int)(y >> 16); - *x++ = y & 0xffff; -#endif - } - while(++i < wds); - if (a) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = a; - b->wds = wds; - } - return b; - } - - static Bigint * -s2b -#ifdef KR_headers - (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; -#else - (CONST char *s, int nd0, int nd, ULong y9) -#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++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int -hi0bits -#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; - } - - static 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 & 1) - return 32; - } - *y = x; - return k; - } - - static 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; - } - - static Bigint * -mult -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int k, wa, wb, wc; - ULong carry, y, z; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; -#ifdef Pack_32 - ULong z2; -#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 Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - 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) { - 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++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static 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) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ - p5 = p5s = i2b(625); - p5->next = 0; - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - p5 = p51; - } - return b; - } - - static 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; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - 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; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#else - if (k &= 0xf) { - 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; - } - - static 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; - } - - static Bigint * -diff -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int i, wa, wb; - Long borrow, y; /* We need signed shifts here. */ - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef Pack_32 - Long z; -#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 Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double -ulp -#ifdef KR_headers - (x) double x; -#else - (double x) -#endif -{ - register 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; - } - - static 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; -#else -#undef d0 -#undef d1 -#endif - return d; - } - - static Bigint * -d2b -#ifdef KR_headers - (d, e, bits) double d; int *e, *bits; -#else - (double d, int *e, int *bits) -#endif -{ - Bigint *b; - int de, i, 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)) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if (y = d1) { - if (k = lo0bits(&y)) { - x[0] = y | z << 32 - k; - z >>= k; - } - else - x[0] = y; - i = b->wds = (x[1] = z) ? 2 : 1; - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - x[0] = z; - i = b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - 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 - - static double -ratio -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - double da, db; - int k, ka, kb; - - da = b2d(a, &ka); - db = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - da *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - db *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return da / db; - } - -static 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 - }; - -#ifdef IEEE_Arith -static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; -#define n_bigtens 5 -#else -#ifdef IBM -static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -static CONST double bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - - double -strtod -#ifdef KR_headers - (s00, se) CONST char *s00; char **se; -#else - (CONST char *s00, char **se) -#endif -{ - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, 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; - -#ifndef KR_headers - CONST char decimal_point = localeconv()->decimal_point[0]; -#else - CONST char decimal_point = '.'; -#endif - - sign = nz0 = nz = 0; - rv = 0.; - - - for(s = s00; isspace((unsigned char) *s); s++) - ; - - if (*s == '-') { - sign = 1; - s++; - } else if (*s == '+') { - s++; - } - - if (*s == '\0') { - s = s00; - goto ret; - } - - if (*s == '0') { - 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; - if (c == decimal_point) { - c = *++s; - 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) { - 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) - s = s00; - 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; - rv = y; - if (k > 9) - rv = tens[k - 9] * rv + z; - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT - && FLT_ROUNDS == 1 -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else - /* rv = */ rounded_product(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. - */ - e -= i; - 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(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(rv, tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(rv, tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if (i = e1 & 15) - rv *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - errno = ERANGE; -#ifdef __STDC__ - rv = HUGE_VAL; -#else - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith - word0(rv) = Exp_mask; - word1(rv) = 0; -#else - word0(rv) = Big0; - word1(rv) = Big1; -#endif -#endif - if (bd0) - goto retfree; - goto ret; - } - if (e1 >>= 4) { - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - rv *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - 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) - rv /= tens[i]; - if (e1 &= ~15) { - e1 >>= 4; - if (e1 >= 1 << n_bigtens) - goto undfl; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - rv *= tinytens[j]; - /* The last multiplication could underflow. */ - rv0 = rv; - rv *= tinytens[j]; - if (!rv) { - rv = 2.*rv0; - rv *= tinytens[j]; - if (!rv) { - undfl: - rv = 0.; - errno = ERANGE; - if (bd0) - goto retfree; - goto ret; - } - word0(rv) = Tiny0; - word1(rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(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 Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else - i = bbe + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j = bbe + (P-Emin); - else - j = P + 1 - bbbits; -#endif - 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; - } - 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); - 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) - 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) == 0xffffffff) { - /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(rv) = 0; - 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 - if (L <= Exp_msk1) -#endif - goto undfl; - L -= Exp_msk1; -#else - L = (word0(rv) & Exp_mask) - Exp_msk1; -#endif - 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) - rv += ulp(rv); -#ifndef ROUND_BIASED - else { - rv -= ulp(rv); -#ifndef Sudden_Underflow - if (!rv) - goto undfl; -#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(FLT_ROUNDS) { - 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 - } - y = word0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - rv0 = rv; - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(rv); - 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 Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - rv0 = rv; - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(rv); - 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(rv); - rv += adj; - } -#else - /* 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(rv); - rv += adj; -#endif - } - z = word0(rv) & Exp_mask; - if (y == z) { - /* Can we stop now? */ - L = 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; - } - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -rv : rv; - } - - static int -quorem -#ifdef KR_headers - (b, S) Bigint *b, *S; -#else - (Bigint *b, Bigint *S) -#endif -{ - int n; - Long borrow, y; - ULong carry, q, ys; - ULong *bx, *bxe, *sx, *sxe; -#ifdef Pack_32 - Long z; - ULong si, zs; -#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 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 >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#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 Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -/* 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. 92-101]. - * - * 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 * -__dtoa -#ifdef KR_headers - (d, mode, ndigits, decpt, sign, rve) - double d; int mode, ndigits, *decpt, *sign; char **rve, char **resultp; -#else - (double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) -#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-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, 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; - - 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; - s = -#ifdef IEEE_Arith - !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : -#endif - "NaN"; - if (rve) - *rve = -#ifdef IEEE_Arith - s[3] ? s + 8 : -#endif - s + 3; - return s; - } -#endif -#ifdef IBM - d += 0; /* normalize */ -#endif - if (!d) { - *decpt = 1; - s = "0"; - if (rve) - *rve = s + 1; - return s; - } - - b = d2b(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))) { -#endif - d2 = d; - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(d2) & Frac_mask)) - 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; - d2 = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (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 (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 = 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; - } - *resultp = (char *) malloc(i + 1); - s = s0 = *resultp; - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - d2 = 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; - d /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - d /= ds; - } - else if (j1 = -k) { - d *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - d *= bigtens[i]; - } - } - if (k_check && d < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - d *= 10.; - ieps++; - } - eps = ieps*d + 7.; - word0(eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - d -= 5.; - if (d > eps) - goto one_digit; - if (d < -eps) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - eps = 0.5/tens[ilim-1] - eps; - for(i = 0;;) { - L = d; - d -= L; - *s++ = '0' + (int)L; - if (d < eps) - goto ret1; - if (1. - d < eps) - goto bump_up; - if (++i >= ilim) - break; - eps *= 10.; - d *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - eps *= tens[ilim-1]; - for(i = 1;; i++, d *= 10.) { - L = d; - d -= L; - *s++ = '0' + (int)L; - if (i == ilim) { - if (d > 0.5 + eps) - goto bump_up; - else if (d < 0.5 - eps) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - 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 || d <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++) { - L = d / ds; - d -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (d < 0) { - L--; - d += ds; - } -#endif - *s++ = '0' + (int)L; - if (i == ilim) { - d += d; - if (d > ds || d == ds && L & 1) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - if (!(d *= 10.)) - break; - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - if (mode < 2) { - 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 - } - 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) - 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. */ - - if (mode < 2) { - if (!word1(d) && !(word0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(d) & Exp_mask -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - else - spec_case = 0; - } - - /* 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) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - 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; - 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 && !(word1(d) & 1)) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || j == 0 && !mode -#ifndef ROUND_BIASED - && !(word1(d) & 1) -#endif - ) { - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) - && dig++ == '9') - goto round_9_up; - } - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *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 */ - - 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 { - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: - Bfree(b); - if (s == s0) { /* don't return empty string */ - *s++ = '0'; - k = 0; - } - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } -#ifdef __cplusplus -} -#endif diff --git a/stdtime/asctime.c b/stdtime/FreeBSD/asctime.c similarity index 80% rename from stdtime/asctime.c rename to stdtime/FreeBSD/asctime.c index c669b54..6b2da41 100644 --- a/stdtime/asctime.c +++ b/stdtime/FreeBSD/asctime.c @@ -1,19 +1,21 @@ /* ** This file is in the public domain, so clarified as of ** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). -** -** $FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.7.6.1 2001/03/05 11:37:20 obrien Exp $ */ +#include #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)asctime.c 7.7"; +static char elsieid[] __unused = "@(#)asctime.c 7.7"; #endif /* !defined NOID */ #endif /* !defined lint */ +__FBSDID("$FreeBSD: src/lib/libc/stdtime/asctime.c,v 1.11 2003/02/16 17:29:11 nectar Exp $"); /*LINTLIBRARY*/ +#include "namespace.h" #include "private.h" +#include "un-namespace.h" #include "tzfile.h" /* @@ -25,14 +27,8 @@ char * asctime(timeptr) const struct tm * timeptr; { - static char *result = NULL; - - if( result == NULL ) { - result = (char *)malloc(3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + - 3 + 2 + 1 + 1); - if( result == NULL ) - return NULL; - } + static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + + 3 + 2 + 1 + 1]; return(asctime_r(timeptr, result)); } @@ -55,8 +51,8 @@ char *result; ** three explicit spaces, two explicit colons, a newline, ** and a trailing ASCII nul). */ - register const char * wn; - register const char * mn; + const char * wn; + const char * mn; if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) wn = "???"; diff --git a/stdtime/ctime.3 b/stdtime/FreeBSD/ctime.3 similarity index 97% rename from stdtime/ctime.3 rename to stdtime/FreeBSD/ctime.3 index fa2895d..fa19de5 100644 --- a/stdtime/ctime.3 +++ b/stdtime/FreeBSD/ctime.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)ctime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdtime/ctime.3,v 1.11.2.6 2001/10/02 11:36:10 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/ctime.3,v 1.20 2002/12/19 09:33:34 ru Exp $ .\" .Dd January 2, 1999 .Dt CTIME 3 @@ -140,15 +140,19 @@ Thu Nov 24 18:22:48 1986\en\e0 .Pp All 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 .Fa buf to store the result, which must be at least 26 characters long. +The .Fn localtime_r and .Fn gmtime_r +functions provide the same functionality as .Fn localtime and @@ -166,7 +170,9 @@ pointed at by to the form shown in the example above. .Pp +The .Fn asctime_r +function provides the same functionality as .Fn asctime except the caller provide the output buffer @@ -183,11 +189,15 @@ 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 @@ -240,7 +250,9 @@ is not set until and .Fa tm_year are determined. -.Fn Mktime +The +.Fn mktime +function returns the specified calendar time; if the calendar time cannot be represented, it returns \-1; .Pp @@ -348,8 +360,10 @@ in the threaded environment.) .Pp The -.Fa tm_zone -field of a returned tm structure points to a static array of characters, +.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 diff --git a/stdtime/difftime.c b/stdtime/FreeBSD/difftime.c similarity index 90% rename from stdtime/difftime.c rename to stdtime/FreeBSD/difftime.c index 5a6c5c6..b7fa1b0 100644 --- a/stdtime/difftime.c +++ b/stdtime/FreeBSD/difftime.c @@ -1,19 +1,21 @@ /* ** This file is in the public domain, so clarified as of ** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). -** -** $FreeBSD: src/lib/libc/stdtime/difftime.c,v 1.4.8.1 2001/03/05 11:37:21 obrien Exp $ */ +#include #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)difftime.c 7.7"; +static char elsieid[] __unused = "@(#)difftime.c 7.7"; #endif /* !defined NOID */ #endif /* !defined lint */ +__FBSDID("$FreeBSD: src/lib/libc/stdtime/difftime.c,v 1.7 2003/02/16 17:29:11 nectar Exp $"); /*LINTLIBRARY*/ +#include "namespace.h" #include "private.h" +#include "un-namespace.h" /* ** Algorithm courtesy Paul Eggert (eggert@twinsun.com). diff --git a/stdtime/localtime.c b/stdtime/FreeBSD/localtime.c similarity index 83% rename from stdtime/localtime.c rename to stdtime/FreeBSD/localtime.c index 680d750..816a94e 100644 --- a/stdtime/localtime.c +++ b/stdtime/FreeBSD/localtime.c @@ -1,15 +1,15 @@ /* ** This file is in the public domain, so clarified as of ** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). -** -** $FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.25.2.1 2001/03/05 11:37:21 obrien Exp $ */ +#include #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)localtime.c 7.57"; +static char elsieid[] __unused = "@(#)localtime.c 7.57"; #endif /* !defined NOID */ #endif /* !defined lint */ +__FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.36 2003/02/16 17:29:11 nectar Exp $"); /* ** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). @@ -19,15 +19,20 @@ static char elsieid[] = "@(#)localtime.c 7.57"; /*LINTLIBRARY*/ +#include "namespace.h" #include #include +#include +#include #include "private.h" +#include "un-namespace.h" + #include "tzfile.h" -#include "fcntl.h" -#ifdef _THREAD_SAFE -#include -#include "pthread_private.h" -#endif + +#include "libc_private.h" + +#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) +#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) /* ** SunOS 4.1.1 headers lack O_BINARY. @@ -118,39 +123,39 @@ struct rule { ** Prototypes for static functions. */ -static long detzcode P((const char * codep)); -static const char * getzname P((const char * strp)); -static const char * getnum P((const char * strp, int * nump, int min, - int max)); -static const char * getsecs P((const char * strp, long * secsp)); -static const char * getoffset P((const char * strp, long * offsetp)); -static const char * getrule P((const char * strp, struct rule * rulep)); -static void gmtload P((struct state * sp)); -static void gmtsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void localsub P((const time_t * timep, long offset, - struct tm * tmp)); -static int increment_overflow P((int * number, int delta)); -static int normalize_overflow P((int * tensptr, int * unitsptr, - int base)); -static void settzname P((void)); -static time_t time1 P((struct tm * tmp, - void(*funcp) P((const time_t *, - long, struct tm *)), - long offset)); -static time_t time2 P((struct tm *tmp, - void(*funcp) P((const time_t *, - long, struct tm*)), - long offset, int * okayp)); -static void timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); -static time_t transtime P((time_t janfirst, int year, - const struct rule * rulep, long offset)); -static int tzload P((const char * name, struct state * sp)); -static int tzparse P((const char * name, struct state * sp, - int lastditch)); +static long detzcode(const char * codep); +static const char * getzname(const char * strp); +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, + struct tm * tmp); +static void localsub(const time_t * timep, long offset, + struct tm * tmp); +static int increment_overflow(int * number, int delta); +static int normalize_overflow(int * tensptr, int * unitsptr, + int base); +static void settzname(void); +static time_t time1(struct tm * tmp, + void(*funcp) (const time_t *, + long, struct tm *), + long offset); +static time_t time2(struct tm *tmp, + void(*funcp) (const time_t *, + long, struct tm*), + long offset, int * okayp); +static void timesub(const time_t * timep, long offset, + const struct state * sp, struct tm * tmp); +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; @@ -169,12 +174,10 @@ static struct state gmtmem; #endif /* !defined TZ_STRLEN_MAX */ static char lcl_TZname[TZ_STRLEN_MAX + 1]; -#ifdef _THREAD_SAFE -static struct pthread_mutex _lcl_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static struct pthread_mutex _gmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t lcl_mutex = &_lcl_mutexd; -static pthread_mutex_t gmt_mutex = &_gmt_mutexd; -#endif +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; char * tzname[2] = { wildabbr, @@ -204,8 +207,8 @@ static long detzcode(codep) const char * const codep; { - register long result; - register int i; + long result; + int i; result = (codep[0] & 0x80) ? ~0L : 0L; for (i = 0; i < 4; ++i) @@ -214,10 +217,10 @@ const char * const codep; } static void -settzname P((void)) +settzname(void) { - register struct state * sp = lclptr; - register int i; + struct state * sp = lclptr; + int i; tzname[0] = wildabbr; tzname[1] = wildabbr; @@ -235,7 +238,7 @@ settzname P((void)) } #endif /* defined ALL_STATE */ for (i = 0; i < sp->typecnt; ++i) { - register const struct ttinfo * const ttisp = &sp->ttis[i]; + const struct ttinfo * const ttisp = &sp->ttis[i]; tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind]; @@ -254,7 +257,7 @@ settzname P((void)) ** And to get the latest zone names into tzname. . . */ for (i = 0; i < sp->timecnt; ++i) { - register const struct ttinfo * const ttisp = + const struct ttinfo * const ttisp = &sp->ttis[ sp->types[i]]; @@ -265,14 +268,12 @@ settzname P((void)) static int tzload(name, sp) -register const char * name; -register struct state * const sp; +const char * name; +struct state * const sp; { - register const char * p; - register int i; - register int fid; - static struct stat sb; - struct stat newsb; + const char * p; + int i; + int fid; /* XXX The following is from OpenBSD, and I'm not sure it is correct */ if (name != NULL && issetugid() != 0) @@ -282,7 +283,7 @@ register struct state * const sp; if (name == NULL && (name = TZDEFAULT) == NULL) return -1; { - register int doaccess; + int doaccess; struct stat stab; /* ** Section 4.9.1 of the C standard says that @@ -311,19 +312,14 @@ register struct state * const sp; doaccess = TRUE; name = fullname; } - if (lstat(name, &newsb) == -1) - return -1; - if( (sb.st_dev == newsb.st_dev) && (sb.st_ino == newsb.st_ino) && - (sb.st_gen == newsb.st_gen) && - (memcmp(&sb.st_ctimespec, &newsb.st_ctimespec, - sizeof(struct timespec)) == 0) ) { - return 0; - } - memcpy(&sb, &newsb, sizeof(sb)); - if ((fid = open(name, OPEN_MODE)) == -1) + 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)) + if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) { + _close(fid); return -1; + } } { struct tzhead * tzhp; @@ -331,8 +327,8 @@ register struct state * const sp; int ttisstdcnt; int ttisgmtcnt; - i = read(fid, buf, sizeof buf); - if (close(fid) != 0) + i = _read(fid, buf, sizeof buf); + if (_close(fid) != 0) return -1; p = buf; p += (sizeof tzhp->tzh_magic) + (sizeof tzhp->tzh_reserved); @@ -373,7 +369,7 @@ register struct state * const sp; return -1; } for (i = 0; i < sp->typecnt; ++i) { - register struct ttinfo * ttisp; + struct ttinfo * ttisp; ttisp = &sp->ttis[i]; ttisp->tt_gmtoff = detzcode(p); @@ -390,7 +386,7 @@ register struct state * const sp; sp->chars[i] = *p++; sp->chars[i] = '\0'; /* ensure '\0' at end */ for (i = 0; i < sp->leapcnt; ++i) { - register struct lsinfo * lsisp; + struct lsinfo * lsisp; lsisp = &sp->lsis[i]; lsisp->ls_trans = detzcode(p); @@ -399,7 +395,7 @@ register struct state * const sp; p += 4; } for (i = 0; i < sp->typecnt; ++i) { - register struct ttinfo * ttisp; + struct ttinfo * ttisp; ttisp = &sp->ttis[i]; if (ttisstdcnt == 0) @@ -412,7 +408,7 @@ register struct state * const sp; } } for (i = 0; i < sp->typecnt; ++i) { - register struct ttinfo * ttisp; + struct ttinfo * ttisp; ttisp = &sp->ttis[i]; if (ttisgmtcnt == 0) @@ -445,9 +441,9 @@ static const int year_lengths[2] = { static const char * getzname(strp) -register const char * strp; +const char * strp; { - register char c; + char c; while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+') @@ -464,13 +460,13 @@ register const char * strp; static const char * getnum(strp, nump, min, max) -register const char * strp; +const char * strp; int * const nump; const int min; const int max; { - register char c; - register int num; + char c; + int num; if (strp == NULL || !is_digit(c = *strp)) return NULL; @@ -497,7 +493,7 @@ const int max; static const char * getsecs(strp, secsp) -register const char * strp; +const char * strp; long * const secsp; { int num; @@ -539,10 +535,10 @@ long * const secsp; static const char * getoffset(strp, offsetp) -register const char * strp; +const char * strp; long * const offsetp; { - register int neg = 0; + int neg = 0; if (*strp == '-') { neg = 1; @@ -567,7 +563,7 @@ long * const offsetp; static const char * getrule(strp, rulep) const char * strp; -register struct rule * const rulep; +struct rule * const rulep; { if (*strp == 'J') { /* @@ -622,12 +618,12 @@ static time_t transtime(janfirst, year, rulep, offset) const time_t janfirst; const int year; -register const struct rule * const rulep; +const struct rule * const rulep; const long offset; { - register int leapyear; - register time_t value; - register int i; + int leapyear; + time_t value; + int i; int d, m1, yy0, yy1, yy2, dow; INITIALIZE(value); @@ -716,7 +712,7 @@ const long offset; static int tzparse(name, sp, lastditch) const char * name; -register struct state * const sp; +struct state * const sp; const int lastditch; { const char * stdname; @@ -725,10 +721,10 @@ const int lastditch; size_t dstlen; long stdoffset; long dstoffset; - register time_t * atp; - register unsigned char * typep; - register char * cp; - register int load_result; + time_t * atp; + unsigned char * typep; + char * cp; + int load_result; INITIALIZE(dstname); stdname = name; @@ -768,8 +764,8 @@ const int lastditch; if (*name == ',' || *name == ';') { struct rule start; struct rule end; - register int year; - register time_t janfirst; + int year; + time_t janfirst; time_t starttime; time_t endtime; @@ -818,12 +814,12 @@ const int lastditch; SECSPERDAY; } } else { - register long theirstdoffset; - register long theirdstoffset; - register long theiroffset; - register int isdst; - register int i; - register int j; + long theirstdoffset; + long theirdstoffset; + long theiroffset; + int isdst; + int i; + int j; if (*name != '\0') return -1; @@ -935,21 +931,12 @@ struct state * const sp; (void) tzparse(gmt, sp, TRUE); } -#ifndef STD_INSPIRED -/* -** A non-static declaration of tzsetwall in a system header file -** may cause a warning about this upcoming static declaration... -*/ -static -#endif /* !defined STD_INSPIRED */ -#ifdef _THREAD_SAFE -void -tzsetwall_basic P((void)) -#else -void -tzsetwall P((void)) -#endif +static void +tzsetwall_basic(void) { + if (lcl_is_set < 0) + return; + lcl_is_set = -1; #ifdef ALL_STATE if (lclptr == NULL) { @@ -965,33 +952,29 @@ tzsetwall P((void)) settzname(); } -#ifdef _THREAD_SAFE void -tzsetwall P((void)) +tzsetwall(void) { - pthread_mutex_lock(&lcl_mutex); + _MUTEX_LOCK(&lcl_mutex); tzsetwall_basic(); - pthread_mutex_unlock(&lcl_mutex); + _MUTEX_UNLOCK(&lcl_mutex); } -#endif -#ifdef _THREAD_SAFE static void -tzset_basic P((void)) -#else -void -tzset P((void)) -#endif +tzset_basic(void) { - register const char * name; + const char * name; name = getenv("TZ"); if (name == NULL) { - tzsetwall(); + tzsetwall_basic(); return; } - if (strlen(name) < sizeof(lcl_TZname)) + if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) + return; + lcl_is_set = (strlen(name) < sizeof(lcl_TZname)); + if (lcl_is_set) (void) strcpy(lcl_TZname, name); #ifdef ALL_STATE @@ -1018,15 +1001,13 @@ tzset P((void)) settzname(); } -#ifdef _THREAD_SAFE void -tzset P((void)) +tzset(void) { - pthread_mutex_lock(&lcl_mutex); + _MUTEX_LOCK(&lcl_mutex); tzset_basic(); - pthread_mutex_unlock(&lcl_mutex); + _MUTEX_UNLOCK(&lcl_mutex); } -#endif /* ** The easy way to behave "as if no library function calls" localtime @@ -1044,9 +1025,9 @@ const time_t * const timep; const long offset; struct tm * const tmp; { - register struct state * sp; - register const struct ttinfo * ttisp; - register int i; + struct state * sp; + const struct ttinfo * ttisp; + int i; const time_t t = *timep; sp = lclptr; @@ -1089,14 +1070,10 @@ localtime_r(timep, p_tm) const time_t * const timep; struct tm *p_tm; { -#ifdef _THREAD_SAFE - pthread_mutex_lock(&lcl_mutex); -#endif - tzset(); + _MUTEX_LOCK(&lcl_mutex); + tzset_basic(); localsub(timep, 0L, p_tm); -#ifdef _THREAD_SAFE - pthread_mutex_unlock(&lcl_mutex); -#endif + _MUTEX_UNLOCK(&lcl_mutex); return(p_tm); } @@ -1104,36 +1081,36 @@ struct tm * localtime(timep) const time_t * const timep; { -#ifdef _THREAD_SAFE - static struct pthread_mutex _localtime_mutex = PTHREAD_MUTEX_STATIC_INITIALIZER; - static pthread_mutex_t localtime_mutex = &_localtime_mutex; + static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t localtime_key = -1; struct tm *p_tm; - pthread_mutex_lock(&localtime_mutex); - if (localtime_key < 0) { - if (pthread_key_create(&localtime_key, free) < 0) { - pthread_mutex_unlock(&localtime_mutex); - return(NULL); + if (__isthreaded != 0) { + _pthread_mutex_lock(&localtime_mutex); + if (localtime_key < 0) { + if (_pthread_key_create(&localtime_key, free) < 0) { + _pthread_mutex_unlock(&localtime_mutex); + return(NULL); + } } + _pthread_mutex_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(); + localsub(timep, 0L, p_tm); + _pthread_mutex_unlock(&lcl_mutex); + return(p_tm); + } else { + tzset_basic(); + localsub(timep, 0L, &tm); + return(&tm); } - 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(); - localsub(timep, 0L, p_tm); - pthread_mutex_unlock(&lcl_mutex); - return p_tm; -#else - tzset(); - localsub(timep, 0L, &tm); - return &tm; -#endif } /* @@ -1146,18 +1123,16 @@ const time_t * const timep; const long offset; struct tm * const tmp; { -#ifdef _THREAD_SAFE - pthread_mutex_lock(&gmt_mutex); -#endif + _MUTEX_LOCK(&gmt_mutex); + if (!gmt_is_set) { + gmt_is_set = TRUE; #ifdef ALL_STATE - if( gmtptr == NULL ) gmtptr = (struct state *) malloc(sizeof *gmtptr); if (gmtptr != NULL) #endif /* defined ALL_STATE */ gmtload(gmtptr); -#ifdef _THREAD_SAFE - pthread_mutex_unlock(&gmt_mutex); -#endif + } + _MUTEX_UNLOCK(&gmt_mutex); timesub(timep, offset, gmtptr, tmp); #ifdef TM_ZONE /* @@ -1184,36 +1159,37 @@ struct tm * gmtime(timep) const time_t * const timep; { -#ifdef _THREAD_SAFE - static struct pthread_mutex _gmtime_mutex = PTHREAD_MUTEX_STATIC_INITIALIZER; - static pthread_mutex_t gmtime_mutex = &_gmtime_mutex; + static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t gmtime_key = -1; struct tm *p_tm; - pthread_mutex_lock(&gmtime_mutex); - if (gmtime_key < 0) { - if (pthread_key_create(&gmtime_key, free) < 0) { - pthread_mutex_unlock(&gmtime_mutex); - return(NULL); + if (__isthreaded != 0) { + _pthread_mutex_lock(&gmtime_mutex); + if (gmtime_key < 0) { + if (_pthread_key_create(&gmtime_key, free) < 0) { + _pthread_mutex_unlock(&gmtime_mutex); + return(NULL); + } } - } - pthread_mutex_unlock(&gmtime_mutex); - /* - * Changed to follow draft 4 pthreads 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_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); } - pthread_setspecific(gmtime_key, p_tm); + gmtsub(timep, 0L, p_tm); + return(p_tm); + } + else { + gmtsub(timep, 0L, &tm); + return(&tm); } - gmtsub(timep, 0L, p_tm); - return(p_tm); -#else - gmtsub(timep, 0L, &tm); - return &tm; -#endif } struct tm * @@ -1240,18 +1216,18 @@ static void timesub(timep, offset, sp, tmp) const time_t * const timep; const long offset; -register const struct state * const sp; -register struct tm * const tmp; +const struct state * const sp; +struct tm * const tmp; { - register const struct lsinfo * lp; - register long days; - register long rem; - register int y; - register int yleap; - register const int * ip; - register long corr; - register int hit; - register int i; + 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; @@ -1315,7 +1291,7 @@ register struct tm * const tmp; 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)]) { - register int newy; + long newy; newy = y + days / DAYSPERNYEAR; if (days < 0) @@ -1395,7 +1371,7 @@ int * const tensptr; int * const unitsptr; const int base; { - register int tensdelta; + int tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : @@ -1406,10 +1382,10 @@ const int base; static int tmcomp(atmp, btmp) -register const struct tm * const atmp; -register const struct tm * const btmp; +const struct tm * const atmp; +const struct tm * const btmp; { - register int result; + int result; if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && @@ -1423,15 +1399,15 @@ register const struct tm * const btmp; static time_t time2(tmp, funcp, offset, okayp) struct tm * const tmp; -void (* const funcp) P((const time_t*, long, struct tm*)); +void (* const funcp)(const time_t*, long, struct tm*); const long offset; int * const okayp; { - register const struct state * sp; - register int dir; - register int bits; - register int i, j ; - register int saved_seconds; + const struct state * sp; + int dir; + int bits; + int i, j ; + int saved_seconds; time_t newt; time_t t; struct tm yourtm, mytm; @@ -1475,7 +1451,9 @@ int * const okayp; } if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) return WRONG; - if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { + 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. @@ -1498,6 +1476,12 @@ int * const okayp; */ 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. @@ -1569,12 +1553,12 @@ label: static time_t time1(tmp, funcp, offset) struct tm * const tmp; -void (* const funcp) P((const time_t *, long, struct tm *)); +void (* const funcp)(const time_t *, long, struct tm *); const long offset; { - register time_t t; - register const struct state * sp; - register int samei, otheri; + time_t t; + const struct state * sp; + int samei, otheri; int okay; if (tmp->tm_isdst > 1) @@ -1633,14 +1617,10 @@ mktime(tmp) struct tm * const tmp; { time_t mktime_return_value; -#ifdef _THREAD_SAFE - pthread_mutex_lock(&lcl_mutex); -#endif - tzset(); + _MUTEX_LOCK(&lcl_mutex); + tzset_basic(); mktime_return_value = time1(tmp, localsub, 0L); -#ifdef _THREAD_SAFE - pthread_mutex_unlock(&lcl_mutex); -#endif + _MUTEX_UNLOCK(&lcl_mutex); return(mktime_return_value); } @@ -1711,9 +1691,9 @@ static long leapcorr(timep) time_t * timep; { - register struct state * sp; - register struct lsinfo * lp; - register int i; + struct state * sp; + struct lsinfo * lp; + int i; sp = lclptr; i = sp->leapcnt; diff --git a/stdtime/FreeBSD/localtime.c.patch b/stdtime/FreeBSD/localtime.c.patch new file mode 100644 index 0000000..11d2cc1 --- /dev/null +++ b/stdtime/FreeBSD/localtime.c.patch @@ -0,0 +1,463 @@ +--- localtime.c.orig Thu Aug 7 18:34:10 2003 ++++ localtime.c Thu Aug 7 16:57:55 2003 +@@ -24,6 +24,18 @@ + #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" + +@@ -119,6 +131,16 @@ + #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. + */ +@@ -138,6 +160,10 @@ + 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 time1(struct tm * tmp, + void(*funcp) (const time_t *, +@@ -174,8 +200,13 @@ + #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 */ + static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; + +@@ -203,6 +234,50 @@ + time_t altzone = 0; + #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; +@@ -233,7 +308,7 @@ + #endif /* defined ALTZONE */ + #ifdef ALL_STATE + if (sp == NULL) { +- tzname[0] = tzname[1] = gmt; ++ tzname[0] = tzname[1] = (char *)gmt; + return; + } + #endif /* defined ALL_STATE */ +@@ -266,6 +341,117 @@ + } + } + ++#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 */ ++} ++ ++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 == 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; +@@ -275,6 +461,9 @@ + 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] == '/') || +@@ -292,7 +481,15 @@ + ** 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; +@@ -300,7 +497,11 @@ + 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, "/"); +@@ -312,6 +513,10 @@ + 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) +@@ -327,6 +532,9 @@ + int ttisstdcnt; + int ttisgmtcnt; + ++#ifdef NOTIFY_TZ_DEBUG ++ NOTIFY_TZ_PRINTF("tzload: reading %s\n", name); ++#endif /* NOTIFY_TZ_DEBUG */ + i = _read(fid, buf, sizeof buf); + if (_close(fid) != 0) + return -1; +@@ -748,6 +956,9 @@ + } + } + 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') { +@@ -934,8 +1145,19 @@ + 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 +@@ -949,12 +1171,18 @@ + #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); +@@ -971,8 +1199,19 @@ + 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; ++ } ++ NOTIFY_TZ_PRINTF("tzset_basic didn't matched %s\n", lcl_TZname); ++#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); +@@ -995,15 +1234,24 @@ + lclptr->ttis[0].tt_gmtoff = 0; + lclptr->ttis[0].tt_abbrind = 0; + (void) strcpy(lclptr->chars, gmt); ++#ifdef NOTIFY_TZ ++ *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); +@@ -1030,6 +1278,9 @@ + 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) { +@@ -1087,7 +1338,7 @@ + + if (__isthreaded != 0) { + _pthread_mutex_lock(&localtime_mutex); +- if (localtime_key < 0) { ++ if (localtime_key == (pthread_key_t)-1) { + if (_pthread_key_create(&localtime_key, free) < 0) { + _pthread_mutex_unlock(&localtime_mutex); + return(NULL); +@@ -1123,14 +1374,30 @@ + 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 +- gmtptr = (struct state *) malloc(sizeof *gmtptr); ++#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); + timesub(timep, offset, gmtptr, tmp); +@@ -1145,7 +1412,7 @@ + else { + #ifdef ALL_STATE + if (gmtptr == NULL) +- tmp->TM_ZONE = gmt; ++ tmp->TM_ZONE = (char *)gmt; + else tmp->TM_ZONE = gmtptr->chars; + #endif /* defined ALL_STATE */ + #ifndef ALL_STATE +@@ -1165,7 +1432,7 @@ + + if (__isthreaded != 0) { + _pthread_mutex_lock(&gmtime_mutex); +- if (gmtime_key < 0) { ++ if (gmtime_key == (pthread_key_t)-1) { + if (_pthread_key_create(&gmtime_key, free) < 0) { + _pthread_mutex_unlock(&gmtime_mutex); + return(NULL); diff --git a/stdtime/private.h b/stdtime/FreeBSD/private.h similarity index 93% rename from stdtime/private.h rename to stdtime/FreeBSD/private.h index 90329d3..5af1c67 100644 --- a/stdtime/private.h +++ b/stdtime/FreeBSD/private.h @@ -1,11 +1,11 @@ -/* $FreeBSD: src/lib/libc/stdtime/private.h,v 1.6.8.1 2000/08/23 00:19:15 jhb Exp $ */ - #ifndef PRIVATE_H #define PRIVATE_H /* ** This file is in the public domain, so clarified as of ** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). +** +** $FreeBSD: src/lib/libc/stdtime/private.h,v 1.9 2002/05/28 16:59:40 alfred Exp $ */ /* Stuff moved from Makefile.inc to reduce clutter */ @@ -106,19 +106,6 @@ static char privatehid[] = "@(#)private.h 7.43"; /* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) -/* -** Workarounds for compilers/systems. -*/ - -#ifndef P -#ifdef __STDC__ -#define P(x) x -#endif /* defined __STDC__ */ -#ifndef __STDC__ -#define P(x) () -#endif /* !defined __STDC__ */ -#endif /* !defined P */ - /* ** SunOS 4.1.1 headers lack FILENAME_MAX. */ diff --git a/stdtime/strftime.3 b/stdtime/FreeBSD/strftime.3 similarity index 90% rename from stdtime/strftime.3 rename to stdtime/FreeBSD/strftime.3 index 1a6f074..5f351cb 100644 --- a/stdtime/strftime.3 +++ b/stdtime/FreeBSD/strftime.3 @@ -34,9 +34,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)strftime.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdtime/strftime.3,v 1.18.2.7 2001/12/14 18:33:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/strftime.3,v 1.33 2003/01/04 09:47:40 tjr Exp $ .\" -.Dd October 4, 1997 +.Dd January 4, 2003 .Dt STRFTIME 3 .Os .Sh NAME @@ -47,7 +47,12 @@ .Sh SYNOPSIS .In time.h .Ft size_t -.Fn strftime "char *buf" "size_t maxsize" "const char *format" "const struct tm *timeptr" +.Fo strftime +.Fa "char * restrict buf" +.Fa "size_t maxsize" +.Fa "const char * restrict format" +.Fa "const struct tm * restrict timeptr" +.Fc .Sh DESCRIPTION The .Fn strftime @@ -76,7 +81,7 @@ NUL character, is not more than .Fn strftime returns the number of characters in the array, not counting the terminating NUL. -Otherwise, zero is returned and the buffer contents is indeterminate. +Otherwise, zero is returned and the buffer contents are indeterminate. .Pp The conversion specifications are copied to the buffer after expansion as follows:- @@ -85,25 +90,17 @@ as follows:- is replaced by national representation of the full weekday name. .It Cm %a is replaced by national representation of -the abbreviated weekday name, where the abbreviation -is the first three characters. +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, where the abbreviation is -the first three characters. +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. -The format is similar to that produced by -.Xr ctime 3 -and is -equivalent to "%a %Ef %T %Y". -It also implies the -"3+1+6+1+8+1+4" format of output. .It Cm \&%D is equivalent to .Dq Li %m/%d/%y . @@ -118,14 +115,15 @@ The sequences are supposed to provide alternate representations. .Pp -Additionly %Ef implemented to represent short month name / day -order of the date, %EF to represent long month name / day -order -and %OB to represent alternative months names +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 @@ -226,7 +224,8 @@ is replaced by .Xr printf 1 , .Xr ctime 3 , .Xr printf 3 , -.Xr strptime 3 +.Xr strptime 3 , +.Xr wcsftime 3 .Sh STANDARDS The .Fn strftime @@ -263,3 +262,9 @@ and 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/strftime.c b/stdtime/FreeBSD/strftime.c similarity index 88% rename from stdtime/strftime.c rename to stdtime/FreeBSD/strftime.c index 21625c7..565c6d1 100644 --- a/stdtime/strftime.c +++ b/stdtime/FreeBSD/strftime.c @@ -15,11 +15,6 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifdef LIBC_RCS -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.25.2.3 2001/02/18 04:06:49 kris Exp $"; -#endif - #ifndef lint #ifndef NOID static const char elsieid[] = "@(#)strftime.c 7.38"; @@ -30,33 +25,33 @@ static const char elsieid[] = "@(#)strftime.c 7.38"; #endif /* !defined NOID */ #endif /* !defined lint */ +#include "namespace.h" #include "private.h" -#ifndef LIBC_SCCS -#ifndef lint +#if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; -#endif /* !defined lint */ -#endif /* !defined LIBC_SCCS */ +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.38 2002/09/06 11:24:03 tjr Exp $"); #include "tzfile.h" #include #include +#include "un-namespace.h" #include "timelocal.h" -static char * _add P((const char *, char *, const char *)); -static char * _conv P((int, const char *, char *, const char *)); -static char * _fmt P((const char *, const struct tm *, char *, const char *)); +static char * _add(const char *, char *, const char *); +static char * _conv(int, const char *, char *, const char *); +static char * _fmt(const char *, const struct tm *, char *, const char *); -size_t strftime P((char *, size_t, const char *, const struct tm *)); +size_t strftime(char * __restrict, size_t, const char * __restrict, + const struct tm * __restrict); extern char * tzname[]; size_t -strftime(s, maxsize, format, t) - char *const s; - const size_t maxsize; - const char *const format; - const struct tm *const t; +strftime(char * __restrict s, size_t maxsize, const char * __restrict format, + const struct tm * __restrict t) { char *p; @@ -76,6 +71,7 @@ _fmt(format, t, pt, ptlim) const char *const ptlim; { int Ealternative, Oalternative; + struct lc_time_T *tptr = __get_current_time_locale(); for ( ; *format; ++format) { if (*format == '%') { @@ -88,24 +84,24 @@ label: break; case 'A': pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? - "?" : Locale->weekday[t->tm_wday], + "?" : tptr->weekday[t->tm_wday], pt, ptlim); continue; case 'a': pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? - "?" : Locale->wday[t->tm_wday], + "?" : tptr->wday[t->tm_wday], pt, ptlim); continue; case 'B': pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? - "?" : (Oalternative ? Locale->alt_month : - Locale->month)[t->tm_mon], + "?" : (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 > 11) ? - "?" : Locale->mon[t->tm_mon], + "?" : tptr->mon[t->tm_mon], pt, ptlim); continue; case 'C': @@ -120,8 +116,7 @@ label: "%02d", pt, ptlim); continue; case 'c': - /* NOTE: c_fmt is intentionally ignored */ - pt = _fmt("%a %Ef %T %Y", t, pt, ptlim); + pt = _fmt(tptr->c_fmt, t, pt, ptlim); continue; case 'D': pt = _fmt("%m/%d/%y", t, pt, ptlim); @@ -156,15 +151,8 @@ label: case 'e': pt = _conv(t->tm_mday, "%2d", pt, ptlim); continue; - case 'f': - if (!Ealternative) - break; - pt = _fmt(Locale->Ef_fmt, t, pt, ptlim); - continue; case 'F': - if (!Ealternative) - break; - pt = _fmt(Locale->EF_fmt, t, pt, ptlim); + pt = _fmt("%Y-%m-%d", t, pt, ptlim); continue; case 'H': pt = _conv(t->tm_hour, "%02d", pt, ptlim); @@ -223,15 +211,15 @@ label: continue; case 'p': pt = _add((t->tm_hour >= 12) ? - Locale->pm : - Locale->am, + tptr->pm : + tptr->am, pt, ptlim); continue; case 'R': pt = _fmt("%H:%M", t, pt, ptlim); continue; case 'r': - pt = _fmt("%I:%M:%S %p", t, pt, ptlim); + pt = _fmt(tptr->ampm_fmt, t, pt, ptlim); continue; case 'S': pt = _conv(t->tm_sec, "%02d", pt, ptlim); @@ -376,10 +364,10 @@ label: pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': - pt = _fmt(Locale->X_fmt, t, pt, ptlim); + pt = _fmt(tptr->X_fmt, t, pt, ptlim); continue; case 'x': - pt = _fmt(Locale->x_fmt, t, pt, ptlim); + pt = _fmt(tptr->x_fmt, t, pt, ptlim); continue; case 'y': pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, @@ -415,7 +403,7 @@ label: }; continue; case '+': - pt = _fmt(Locale->date_fmt, t, pt, ptlim); + pt = _fmt(tptr->date_fmt, t, pt, ptlim); continue; case '%': /* diff --git a/stdtime/strptime.3 b/stdtime/FreeBSD/strptime.3 similarity index 83% rename from stdtime/strptime.3 rename to stdtime/FreeBSD/strptime.3 index eedf7d1..761c919 100644 --- a/stdtime/strptime.3 +++ b/stdtime/FreeBSD/strptime.3 @@ -23,9 +23,9 @@ .\" (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.9.2.7 2001/12/14 18:33:59 ru Exp $ +.\" $FreeBSD: src/lib/libc/stdtime/strptime.3,v 1.22 2003/01/04 09:50:04 tjr Exp $ .\" " -.Dd May 8, 1997 +.Dd January 4, 2003 .Dt STRPTIME 3 .Os .Sh NAME @@ -36,7 +36,11 @@ .Sh SYNOPSIS .In time.h .Ft char * -.Fn strptime "const char *buf" "const char *format" "struct tm *timeptr" +.Fo strptime +.Fa "const char * restrict buf" +.Fa "const char * restrict format" +.Fa "struct tm * restrict timeptr" +.Fc .Sh DESCRIPTION The .Fn strptime @@ -67,6 +71,29 @@ and 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 timeptr +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 timeptr +structure with today's date before passing it to +.Fn strptime . .Sh RETURN VALUES Upon successful completion, .Fn strptime @@ -137,3 +164,9 @@ 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/strptime.c b/stdtime/FreeBSD/strptime.c similarity index 80% rename from stdtime/strptime.c rename to stdtime/FreeBSD/strptime.c index 7b6c7f7..fab419c 100644 --- a/stdtime/strptime.c +++ b/stdtime/FreeBSD/strptime.c @@ -51,48 +51,40 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef LIBC_RCS -static const char rcsid[] = - "$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.17.2.2 2001/07/31 00:06:24 dd Exp $"; -#endif - +#include #ifndef lint #ifndef NOID -static char copyright[] = +static char copyright[] __unused = "@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; -static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; +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.34 2003/04/30 10:25:57 mtm Exp $"); +#include "namespace.h" #include #include #include #include #include -#ifdef _THREAD_SAFE #include -#include "pthread_private.h" -#endif +#include "un-namespace.h" +#include "libc_private.h" #include "timelocal.h" -static char * _strptime(const char *, const char *, struct tm *); - -#ifdef _THREAD_SAFE -static struct pthread_mutex _gotgmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t gotgmt_mutex = &_gotgmt_mutexd; -#endif -static int got_GMT; +static char * _strptime(const char *, const char *, struct tm *, int *); #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) static char * -_strptime(const char *buf, const char *fmt, struct tm *tm) +_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) { char c; const char *ptr; int i, len; int Ealternative, Oalternative; + struct lc_time_T *tptr = __get_current_time_locale(); ptr = fmt; while (*ptr != 0) { @@ -122,7 +114,7 @@ label: break; case '+': - buf = _strptime(buf, Locale->date_fmt, tm); + buf = _strptime(buf, tptr->date_fmt, tm, GMTp); if (buf == 0) return 0; break; @@ -145,14 +137,13 @@ label: break; case 'c': - /* NOTE: c_fmt is intentionally ignored */ - buf = _strptime(buf, "%a %Ef %T %Y", tm); + buf = _strptime(buf, tptr->c_fmt, tm, GMTp); if (buf == 0) return 0; break; case 'D': - buf = _strptime(buf, "%m/%d/%y", tm); + buf = _strptime(buf, "%m/%d/%y", tm, GMTp); if (buf == 0) return 0; break; @@ -170,40 +161,37 @@ label: goto label; case 'F': - case 'f': - if (!Ealternative) - break; - buf = _strptime(buf, (c == 'f') ? Locale->Ef_fmt : Locale->EF_fmt, tm); + buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); if (buf == 0) return 0; break; case 'R': - buf = _strptime(buf, "%H:%M", tm); + buf = _strptime(buf, "%H:%M", tm, GMTp); if (buf == 0) return 0; break; case 'r': - buf = _strptime(buf, "%I:%M:%S %p", tm); + buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp); if (buf == 0) return 0; break; case 'T': - buf = _strptime(buf, "%H:%M:%S", tm); + buf = _strptime(buf, "%H:%M:%S", tm, GMTp); if (buf == 0) return 0; break; case 'X': - buf = _strptime(buf, Locale->X_fmt, tm); + buf = _strptime(buf, tptr->X_fmt, tm, GMTp); if (buf == 0) return 0; break; case 'x': - buf = _strptime(buf, Locale->x_fmt, tm); + buf = _strptime(buf, tptr->x_fmt, tm, GMTp); if (buf == 0) return 0; break; @@ -293,8 +281,8 @@ label: * XXX This is bogus if parsed before hour-related * specifiers. */ - len = strlen(Locale->am); - if (strncasecmp(buf, Locale->am, len) == 0) { + len = strlen(tptr->am); + if (strncasecmp(buf, tptr->am, len) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) @@ -303,8 +291,8 @@ label: break; } - len = strlen(Locale->pm); - if (strncasecmp(buf, Locale->pm, len) == 0) { + len = strlen(tptr->pm); + if (strncasecmp(buf, tptr->pm, len) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) @@ -317,22 +305,17 @@ label: case 'A': case 'a': - for (i = 0; i < asizeof(Locale->weekday); i++) { - if (c == 'A') { - len = strlen(Locale->weekday[i]); - if (strncasecmp(buf, - Locale->weekday[i], - len) == 0) - break; - } else { - len = strlen(Locale->wday[i]); - if (strncasecmp(buf, - Locale->wday[i], - len) == 0) - break; - } + for (i = 0; i < asizeof(tptr->weekday); i++) { + len = strlen(tptr->weekday[i]); + if (strncasecmp(buf, tptr->weekday[i], + len) == 0) + break; + len = strlen(tptr->wday[i]); + if (strncasecmp(buf, tptr->wday[i], + len) == 0) + break; } - if (i == asizeof(Locale->weekday)) + if (i == asizeof(tptr->weekday)) return 0; tm->tm_wday = i; @@ -411,32 +394,27 @@ label: case 'B': case 'b': case 'h': - for (i = 0; i < asizeof(Locale->month); i++) { + for (i = 0; i < asizeof(tptr->month); i++) { if (Oalternative) { if (c == 'B') { - len = strlen(Locale->alt_month[i]); + len = strlen(tptr->alt_month[i]); if (strncasecmp(buf, - Locale->alt_month[i], + tptr->alt_month[i], len) == 0) break; } } else { - if (c == 'B') { - len = strlen(Locale->month[i]); - if (strncasecmp(buf, - Locale->month[i], - len) == 0) - break; - } else { - len = strlen(Locale->mon[i]); - if (strncasecmp(buf, - Locale->mon[i], - len) == 0) - break; - } + len = strlen(tptr->month[i]); + if (strncasecmp(buf, tptr->month[i], + len) == 0) + break; + len = strlen(tptr->mon[i]); + if (strncasecmp(buf, tptr->mon[i], + len) == 0) + break; } } - if (i == asizeof(Locale->month)) + if (i == asizeof(tptr->month)) return 0; tm->tm_mon = i; @@ -473,7 +451,7 @@ label: return 0; buf = cp; gmtime_r(&t, tm); - got_GMT = 1; + *GMTp = 1; } break; @@ -517,7 +495,7 @@ label: zonestr[cp - buf] = '\0'; tzset(); if (0 == strcmp(zonestr, "GMT")) { - got_GMT = 1; + *GMTp = 1; } else if (0 == strcmp(zonestr, tzname[0])) { tm->tm_isdst = 0; } else if (0 == strcmp(zonestr, tzname[1])) { @@ -536,25 +514,18 @@ label: char * -strptime(const char *buf, const char *fmt, struct tm *tm) +strptime(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm) { char *ret; + int gmt; -#ifdef _THREAD_SAFE - pthread_mutex_lock(&gotgmt_mutex); -#endif - - got_GMT = 0; - ret = _strptime(buf, fmt, tm); - if (ret && got_GMT) { + gmt = 0; + ret = _strptime(buf, fmt, tm, &gmt); + if (ret && gmt) { time_t t = timegm(tm); - localtime_r(&t, tm); - got_GMT = 0; + localtime_r(&t, tm); } -#ifdef _THREAD_SAFE - pthread_mutex_unlock(&gotgmt_mutex); -#endif - - return ret; + return (ret); } diff --git a/stdtime/time2posix.3 b/stdtime/FreeBSD/time2posix.3 similarity index 97% rename from stdtime/time2posix.3 rename to stdtime/FreeBSD/time2posix.3 index cc6bd49..01a8e51 100644 --- a/stdtime/time2posix.3 +++ b/stdtime/FreeBSD/time2posix.3 @@ -1,4 +1,4 @@ -.\" $FreeBSD: src/lib/libc/stdtime/time2posix.3,v 1.9.2.4 2001/12/14 18:33:59 ru Exp $ +.\" $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 diff --git a/stdtime/FreeBSD/time2posix.3.patch b/stdtime/FreeBSD/time2posix.3.patch new file mode 100644 index 0000000..9ec54fd --- /dev/null +++ b/stdtime/FreeBSD/time2posix.3.patch @@ -0,0 +1,14 @@ +--- time2posix.3.orig Tue May 20 15:23:48 2003 ++++ time2posix.3 Tue May 27 12:02:20 2003 +@@ -12,9 +12,9 @@ + .Sh SYNOPSIS + .In time.h + .Ft time_t +-.Fn time2posix "const time_t *t" ++.Fn time2posix "time_t t" + .Ft time_t +-.Fn posix2time "const time_t *t" ++.Fn posix2time "time_t t" + .Sh DESCRIPTION + .St -p1003.1-88 + legislates that a time_t value of diff --git a/stdtime/FreeBSD/time32.c b/stdtime/FreeBSD/time32.c new file mode 100644 index 0000000..5085dd7 --- /dev/null +++ b/stdtime/FreeBSD/time32.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/FreeBSD/timelocal.c b/stdtime/FreeBSD/timelocal.c new file mode 100644 index 0000000..87312f4 --- /dev/null +++ b/stdtime/FreeBSD/timelocal.c @@ -0,0 +1,117 @@ +/*- + * 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.24 2002/08/07 16:49:20 ache Exp $"); + +#include + +#include "ldpart.h" +#include "timelocal.h" + +static struct lc_time_T _time_locale; +static int _time_using_locale; +static char *time_locale_buf; + +#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" +}; + +struct lc_time_T * +__get_current_time_locale(void) +{ + return (_time_using_locale + ? &_time_locale + : (struct lc_time_T *)&_C_time_locale); +} + +int +__time_load_locale(const char *name) +{ + return (__part_load_locale(name, &_time_using_locale, + time_locale_buf, "LC_TIME", + LCTIME_SIZE, LCTIME_SIZE, + (const char **)&_time_locale)); +} diff --git a/stdtime/FreeBSD/timelocal.c.patch b/stdtime/FreeBSD/timelocal.c.patch new file mode 100644 index 0000000..f8ffb51 --- /dev/null +++ b/stdtime/FreeBSD/timelocal.c.patch @@ -0,0 +1,11 @@ +--- timelocal.c.orig Tue May 20 15:23:48 2003 ++++ timelocal.c Wed Jun 11 17:08:39 2003 +@@ -111,7 +111,7 @@ + __time_load_locale(const char *name) + { + return (__part_load_locale(name, &_time_using_locale, +- time_locale_buf, "LC_TIME", ++ &time_locale_buf, "LC_TIME", + LCTIME_SIZE, LCTIME_SIZE, + (const char **)&_time_locale)); + } diff --git a/stdtime/timelocal.h b/stdtime/FreeBSD/timelocal.h similarity index 68% rename from stdtime/timelocal.h rename to stdtime/FreeBSD/timelocal.h index e1f9694..0b0a59a 100644 --- a/stdtime/timelocal.h +++ b/stdtime/FreeBSD/timelocal.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1997 FreeBSD Inc. + * Copyright (c) 1997-2002 FreeBSD Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,32 +23,33 @@ * 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.5.2.1 2000/10/26 16:21:35 ache Exp $ + * $FreeBSD: src/lib/libc/stdtime/timelocal.h,v 1.11 2002/01/24 15:07:44 phantom Exp $ */ +#ifndef _TIMELOCAL_H_ +#define _TIMELOCAL_H_ + /* * 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; /* not used, just compatibility placeholder */ - const char * am; - const char * pm; - const char * date_fmt; - const char * alt_month[12]; - const char * Ef_fmt; - const char * EF_fmt; + 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; }; -extern struct lc_time_T _time_localebuf; -extern int _time_using_locale; -extern const struct lc_time_T _C_time_locale; - -#define Locale (_time_using_locale ? &_time_localebuf : &_C_time_locale) +struct lc_time_T *__get_current_time_locale(void); +int __time_load_locale(const char *); +#endif /* !_TIMELOCAL_H_ */ diff --git a/stdtime/tzfile.5 b/stdtime/FreeBSD/tzfile.5 similarity index 97% rename from stdtime/tzfile.5 rename to stdtime/FreeBSD/tzfile.5 index 25ad3e6..04ecce8 100644 --- a/stdtime/tzfile.5 +++ b/stdtime/FreeBSD/tzfile.5 @@ -1,4 +1,4 @@ -.\" $FreeBSD: src/lib/libc/stdtime/tzfile.5,v 1.8.2.2 2001/08/17 15:42:43 ru Exp $ +.\" $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 diff --git a/stdtime/tzfile.h b/stdtime/FreeBSD/tzfile.h similarity index 98% rename from stdtime/tzfile.h rename to stdtime/FreeBSD/tzfile.h index c1b27ea..378d7ae 100644 --- a/stdtime/tzfile.h +++ b/stdtime/FreeBSD/tzfile.h @@ -1,10 +1,12 @@ #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 $ */ /* diff --git a/stdtime/Makefile.inc b/stdtime/Makefile.inc index 12c4b0c..7782481 100644 --- a/stdtime/Makefile.inc +++ b/stdtime/Makefile.inc @@ -1,13 +1,21 @@ # Makefile.inc,v 1.2 1994/09/13 21:26:01 wollman Exp -# $FreeBSD: src/lib/libc/stdtime/Makefile.inc,v 1.13 2001/10/28 19:54:49 dillon Exp $ +# $FreeBSD: src/lib/libc/stdtime/Makefile.inc,v 1.14 2002/11/18 09:50:56 ru Exp $ -.PATH: ${.CURDIR}/stdtime ${.CURDIR}/locale +.PATH: ${.CURDIR}/stdtime -SRCS+= timelocal.c asctime.c difftime.c localtime.c strftime.c strptime.c +CFLAGS += -DNOTIFY_TZ + +.include "Makefile.fbsd_begin" +FBSDSRCS= asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c \ + time32.c +FBSDORIGHDRS= private.h timelocal.h tzfile.h +.include "Makefile.fbsd_end" .if ${LIB} == "c" -MAN3+= ctime.3 strftime.3 strptime.3 time2posix.3 -MAN5+= tzfile.5 +.include "Makefile.fbsd_begin" +FBSDMAN3= ctime.3 strftime.3 strptime.3 time2posix.3 +FBSDMAN5= tzfile.5 +.include "Makefile.fbsd_end" MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \ ctime.3 localtime.3 ctime.3 mktime.3 ctime.3 timegm.3 \ diff --git a/stdtime/timelocal.c b/stdtime/timelocal.c deleted file mode 100644 index 514d3f1..0000000 --- a/stdtime/timelocal.c +++ /dev/null @@ -1,244 +0,0 @@ -/*- - * 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. - * - * $FreeBSD: src/lib/libc/stdtime/timelocal.c,v 1.8.2.2 2000/10/26 16:21:35 ache Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "setlocale.h" -#include "timelocal.h" - -static int split_lines(char *, const char *); -static void set_from_buf(const char *, int); - -struct lc_time_T _time_localebuf; -int _time_using_locale; - -#define LCTIME_SIZE_FULL (sizeof(struct lc_time_T) / sizeof(char *)) -#define LCTIME_SIZE_1 \ - (offsetof(struct lc_time_T, alt_month[0]) / sizeof(char *)) -#define LCTIME_SIZE_2 \ - (offsetof(struct lc_time_T, Ef_fmt) / sizeof(char *)) - -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 (ctime-compatible) - ** Not used, just compatibility placeholder. - */ - NULL, - - /* am */ - "AM", - - /* pm */ - "PM", - - /* date_fmt */ - "%a %Ef %X %Z %Y", - - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, - - /* Ef_fmt - ** To determine short months / day order - */ - "%b %e", - - /* EF_fmt - ** To determine long months / day order - */ - "%B %e" -}; - - -int -__time_load_locale(const char *name) -{ - static char * locale_buf; - static char locale_buf_C[] = "C"; - static int num_lines; - - int fd; - char * lbuf; - char * p; - const char * plim; - char filename[PATH_MAX]; - struct stat st; - size_t namesize; - size_t bufsize; - int save_using_locale; - - save_using_locale = _time_using_locale; - _time_using_locale = 0; - - if (name == NULL) - goto no_locale; - - if (!strcmp(name, "C") || !strcmp(name, "POSIX")) - return 0; - - /* - ** If the locale name is the same as our cache, use the cache. - */ - lbuf = locale_buf; - if (lbuf != NULL && strcmp(name, lbuf) == 0) { - set_from_buf(lbuf, num_lines); - _time_using_locale = 1; - return 0; - } - /* - ** Slurp the locale file into the cache. - */ - namesize = strlen(name) + 1; - - if (!_PathLocale) - goto no_locale; - /* Range checking not needed, 'name' size is limited */ - strcpy(filename, _PathLocale); - strcat(filename, "/"); - strcat(filename, name); - strcat(filename, "/LC_TIME"); - fd = open(filename, O_RDONLY); - if (fd < 0) - goto no_locale; - if (fstat(fd, &st) != 0) - goto bad_locale; - if (st.st_size <= 0) - goto bad_locale; - bufsize = namesize + st.st_size; - locale_buf = NULL; - lbuf = (lbuf == NULL || lbuf == locale_buf_C) ? - malloc(bufsize) : reallocf(lbuf, bufsize); - if (lbuf == NULL) - 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; - if (close(fd) != 0) - goto bad_lbuf; - /* - ** Parse the locale file into localebuf. - */ - if (plim[-1] != '\n') - goto bad_lbuf; - num_lines = split_lines(p, plim); - if (num_lines >= LCTIME_SIZE_FULL) - num_lines = LCTIME_SIZE_FULL; - else if (num_lines >= LCTIME_SIZE_2) - num_lines = LCTIME_SIZE_2; - else if (num_lines >= LCTIME_SIZE_1) - num_lines = LCTIME_SIZE_1; - else - goto reset_locale; - set_from_buf(lbuf, num_lines); - /* - ** Record the successful parse in the cache. - */ - locale_buf = lbuf; - - _time_using_locale = 1; - return 0; - -reset_locale: - /* - * XXX - This may not be the correct thing to do in this case. - * setlocale() assumes that we left the old locale alone. - */ - locale_buf = locale_buf_C; - _time_localebuf = _C_time_locale; - save_using_locale = 0; -bad_lbuf: - free(lbuf); -bad_locale: - (void)close(fd); -no_locale: - _time_using_locale = save_using_locale; - return -1; -} - -static int -split_lines(char *p, const char *plim) -{ - int i; - - for (i = 0; p < plim; i++) { - p = strchr(p, '\n'); - *p++ = '\0'; - } - return i; -} - -static void -set_from_buf(const char *p, int num_lines) -{ - const char **ap; - int i; - - for (ap = (const char **) &_time_localebuf, i = 0; - i < num_lines; ++ap, ++i) - *ap = p += strlen(p) + 1; - if (num_lines >= LCTIME_SIZE_2) - return; - for (i = 0; i < 12; i++) - _time_localebuf.alt_month[i] = _time_localebuf.month[i]; -} diff --git a/string/bcmp.3 b/string/FreeBSD/bcmp.3 similarity index 92% rename from string/bcmp.3 rename to string/FreeBSD/bcmp.3 index 60bd887..e6b18be 100644 --- a/string/bcmp.3 +++ b/string/FreeBSD/bcmp.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.9 2002/08/30 21:07:40 robert Exp $ .\" .Dd June 4, 1993 .Dt BCMP 3 @@ -43,7 +43,7 @@ .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" .Sh DESCRIPTION @@ -72,3 +72,10 @@ A .Fn bcmp function first appeared in .Bx 4.2 . +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/i386/gen/bcmp.c b/string/FreeBSD/bcmp.c similarity index 61% rename from i386/gen/bcmp.c rename to string/FreeBSD/bcmp.c index 7fdc3f0..f5227df 100644 --- a/i386/gen/bcmp.c +++ b/string/FreeBSD/bcmp.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,35 +31,29 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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 +#include /* * bcmp -- vax cmpc3 instruction */ int -bcmp(b1, b2, length) - const void *b1, *b2; - register size_t length; +bcmp(const void *b1, const void *b2, size_t length) { - register char *p1, *p2; + char *p1, *p2; if (length == 0) - return(0); + return (0); p1 = (char *)b1; p2 = (char *)b2; do if (*p1++ != *p2++) break; while (--length); - return(length); + return (length); } - -#else -#warning ----------- Check for implementation of bcmp() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/string/bcopy.3 b/string/FreeBSD/bcopy.3 similarity index 91% rename from string/bcopy.3 rename to string/FreeBSD/bcopy.3 index a239409..5c54ca8 100644 --- a/string/bcopy.3 +++ b/string/FreeBSD/bcopy.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcopy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcopy.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bcopy.3,v 1.8 2002/09/01 21:53:46 robert Exp $ .\" .Dd June 4, 1993 .Dt BCOPY 3 @@ -44,7 +44,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In strings.h .Ft void .Fn bcopy "const void *src" "void *dst" "size_t len" .Sh DESCRIPTION @@ -72,3 +72,10 @@ A .Fn bcopy function appeared in .Bx 4.2 . +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/FreeBSD/bcopy.c b/string/FreeBSD/bcopy.c new file mode 100644 index 0000000..1b2bd0c --- /dev/null +++ b/string/FreeBSD/bcopy.c @@ -0,0 +1,139 @@ +/*- + * 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[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/bcopy.c,v 1.5 2002/09/01 21:53:46 robert Exp $"); + +/* + * sizeof(word) MUST BE A POWER OF TWO + * SO THAT wmask BELOW IS ALL ONES + */ +typedef int word; /* "word" used for optimal copy speed */ + +#define wsize sizeof(word) +#define wmask (wsize - 1) + +/* + * Copy a block of memory, handling overlap. + * This is the routine that actually implements + * (the portable versions of) bcopy, memcpy, and memmove. + */ +#if defined(MEMCOPY) || defined(MEMMOVE) +#include + +void * +#ifdef MEMCOPY +memcpy +#else +memmove +#endif +(void *dst0, const void *src0, size_t length) +#else +#include + +void +bcopy(const void *src0, void *dst0, size_t length) +#endif +{ + char *dst = dst0; + const char *src = src0; + size_t t; + + if (length == 0 || dst == src) /* nothing to do */ + goto done; + + /* + * Macros: loop-t-times; and loop-t-times, t>0 + */ +#define TLOOP(s) if (t) TLOOP1(s) +#define TLOOP1(s) do { s; } while (--t) + + if ((unsigned long)dst < (unsigned long)src) { + /* + * Copy forward. + */ + t = (int)src; /* only need low bits */ + if ((t | (int)dst) & wmask) { + /* + * Try to align operands. This cannot be done + * unless the low bits match. + */ + if ((t ^ (int)dst) & wmask || length < wsize) + t = length; + else + t = wsize - (t & wmask); + length -= t; + TLOOP1(*dst++ = *src++); + } + /* + * Copy whole words, then mop up any trailing bytes. + */ + t = length / wsize; + TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); + t = length & wmask; + TLOOP(*dst++ = *src++); + } else { + /* + * Copy backwards. Otherwise essentially the same. + * Alignment works as before, except that it takes + * (t&wmask) bytes to align, not wsize-(t&wmask). + */ + src += length; + dst += length; + t = (int)src; + if ((t | (int)dst) & wmask) { + if ((t ^ (int)dst) & wmask || length <= wsize) + t = length; + else + t &= wmask; + length -= t; + TLOOP1(*--dst = *--src); + } + t = length / wsize; + TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); + t = length & wmask; + TLOOP(*--dst = *--src); + } +done: +#if defined(MEMCOPY) || defined(MEMMOVE) + return (dst0); +#else + return; +#endif +} diff --git a/string/bstring.3 b/string/FreeBSD/bstring.3 similarity index 100% rename from string/bstring.3 rename to string/FreeBSD/bstring.3 diff --git a/string/bzero.3 b/string/FreeBSD/bzero.3 similarity index 91% rename from string/bzero.3 rename to string/FreeBSD/bzero.3 index faa16fe..3cc05e0 100644 --- a/string/bzero.3 +++ b/string/FreeBSD/bzero.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)bzero.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bzero.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/bzero.3,v 1.8 2002/09/01 21:53:46 robert Exp $ .\" .Dd June 4, 1993 .Dt BZERO 3 @@ -44,7 +44,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In strings.h .Ft void .Fn bzero "void *b" "size_t len" .Sh DESCRIPTION @@ -69,3 +69,10 @@ A function appeared in .Bx 4.3 . +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/FreeBSD/bzero.c b/string/FreeBSD/bzero.c new file mode 100644 index 0000000..85bc5e8 --- /dev/null +++ b/string/FreeBSD/bzero.c @@ -0,0 +1,5 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/bzero.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + +#define BZERO +#include "memset.c" diff --git a/string/FreeBSD/bzero.c.patch b/string/FreeBSD/bzero.c.patch new file mode 100644 index 0000000..1f2956a --- /dev/null +++ b/string/FreeBSD/bzero.c.patch @@ -0,0 +1,8 @@ +--- bzero.c.orig Fri Mar 22 13:53:19 2002 ++++ bzero.c Sat May 3 14:33:50 2003 +@@ -2,4 +2,4 @@ + __FBSDID("$FreeBSD: src/lib/libc/string/bzero.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + + #define BZERO +-#include "memset.c" ++#include "memset-fbsd.c" diff --git a/string/ffs.3 b/string/FreeBSD/ffs.3 similarity index 91% rename from string/ffs.3 rename to string/FreeBSD/ffs.3 index 665d9da..ed6ccd8 100644 --- a/string/ffs.3 +++ b/string/FreeBSD/ffs.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)ffs.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.5 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.6 2002/08/30 19:08:53 robert Exp $ .\" .Dd April 19, 1994 .Dt FFS 3 @@ -43,7 +43,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In strings.h .Ft int .Fn ffs "int value" .Sh DESCRIPTION @@ -62,3 +62,10 @@ The .Fn ffs function appeared in .Bx 4.3 . +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/i386/gen/ffs.c b/string/FreeBSD/ffs.c similarity index 62% rename from i386/gen/ffs.c rename to string/FreeBSD/ffs.c index 08a7f2c..c977cfd 100644 --- a/i386/gen/ffs.c +++ b/string/FreeBSD/ffs.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,22 +31,21 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)ffs.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/ffs.c,v 1.5 2002/08/30 19:08:53 robert Exp $"); -#include +#include /* * ffs -- vax ffs instruction */ int -ffs(mask) - register int mask; +ffs(int mask) { - register int bit; + int bit; if (mask == 0) return(0); @@ -78,7 +53,3 @@ ffs(mask) mask >>= 1; return(bit); } - -#else -#warning ----------- Check for implementation of ffs() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/string/index.3 b/string/FreeBSD/index.3 similarity index 92% rename from string/index.3 rename to string/FreeBSD/index.3 index 309a39c..12c663e 100644 --- a/string/index.3 +++ b/string/FreeBSD/index.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)index.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/index.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/index.3,v 1.8 2002/12/18 13:33:03 ru Exp $ .\" .Dd June 4, 1993 .Dt INDEX 3 @@ -43,7 +43,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In strings.h .Ft char * .Fn index "const char *s" "int c" .Sh DESCRIPTION @@ -53,7 +53,7 @@ function locates the first character matching .Fa c (converted to a -.Em char ) +.Vt char ) in the null-terminated string .Fa s . .Sh RETURN VALUES @@ -81,3 +81,10 @@ A .Fn index 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/index.c b/string/FreeBSD/index.c similarity index 62% rename from string/index.c rename to string/FreeBSD/index.c index 1d3f12e..c0eeafa 100644 --- a/string/index.c +++ b/string/FreeBSD/index.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,23 +31,32 @@ * 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 -#include +__FBSDID("$FreeBSD: src/lib/libc/string/index.c,v 1.5 2002/08/30 19:42:07 robert Exp $"); + #include -char * #ifdef STRCHR -strchr(p, ch) +#include + +char * +strchr #else -index(p, ch) +#include + +char * +index #endif - register const char *p, ch; +(const char *p, int ch) { for (;; ++p) { if (*p == ch) - return((char *)p); - if (!*p) - return((char *)NULL); + return ((char *)p); + if (*p == '\0') + return (NULL); } /* NOTREACHED */ } diff --git a/string/memccpy.3 b/string/FreeBSD/memccpy.3 similarity index 100% rename from string/memccpy.3 rename to string/FreeBSD/memccpy.3 diff --git a/string/memccpy.c b/string/FreeBSD/memccpy.c similarity index 63% rename from string/memccpy.c rename to string/FreeBSD/memccpy.c index 2806668..0bc6a11 100644 --- a/string/memccpy.c +++ b/string/FreeBSD/memccpy.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,8 +31,12 @@ * 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 * @@ -64,13 +44,13 @@ memccpy(t, f, c, n) void *t; const void *f; int c; - register size_t n; + size_t n; { if (n) { - register unsigned char *tp = t; - register const unsigned char *fp = f; - register unsigned char uc = c; + unsigned char *tp = t; + const unsigned char *fp = f; + unsigned char uc = c; do { if ((*tp++ = *fp++) == uc) return (tp); diff --git a/string/memchr.3 b/string/FreeBSD/memchr.3 similarity index 100% rename from string/memchr.3 rename to string/FreeBSD/memchr.3 diff --git a/string/memchr.c b/string/FreeBSD/memchr.c similarity index 66% rename from string/memchr.c rename to string/FreeBSD/memchr.c index 358c356..e3c6679 100644 --- a/string/memchr.c +++ b/string/FreeBSD/memchr.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -61,18 +37,19 @@ #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; - register unsigned char c; - register size_t n; + unsigned char c; + size_t n; { if (n != 0) { - register const unsigned char *p = s; + const unsigned char *p = s; do { if (*p++ == c) diff --git a/string/memcmp.3 b/string/FreeBSD/memcmp.3 similarity index 100% rename from string/memcmp.3 rename to string/FreeBSD/memcmp.3 diff --git a/string/memcmp.c b/string/FreeBSD/memcmp.c similarity index 64% rename from string/memcmp.c rename to string/FreeBSD/memcmp.c index f7488a6..045e4d9 100644 --- a/string/memcmp.c +++ b/string/FreeBSD/memcmp.c @@ -1,31 +1,10 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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 +/*- + * 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: @@ -55,7 +34,12 @@ * 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 /* @@ -67,7 +51,7 @@ memcmp(s1, s2, n) size_t n; { if (n != 0) { - register const unsigned char *p1 = s1, *p2 = s2; + const unsigned char *p1 = s1, *p2 = s2; do { if (*p1++ != *p2++) diff --git a/string/memcpy.3 b/string/FreeBSD/memcpy.3 similarity index 94% rename from string/memcpy.3 rename to string/FreeBSD/memcpy.3 index 311fbec..ba9cae9 100644 --- a/string/memcpy.3 +++ b/string/FreeBSD/memcpy.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memcpy.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $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 @@ -82,5 +82,10 @@ is implemented using .Xr bcopy 3 , and therefore the strings may overlap. On other systems, copying overlapping strings may produce surprises. -A simpler solution is to not use -.Fn memcpy . +Programs intended to be portable should use +.Xr memmove 3 +when +.Fa src +and +.Fa dst +may overlap. diff --git a/string/FreeBSD/memcpy.3.patch b/string/FreeBSD/memcpy.3.patch new file mode 100644 index 0000000..f4f83f9 --- /dev/null +++ b/string/FreeBSD/memcpy.3.patch @@ -0,0 +1,39 @@ +--- memcpy.3.orig Tue May 20 15:23:54 2003 ++++ memcpy.3 Sat Jun 21 06:17:05 2003 +@@ -58,6 +58,18 @@ + .Fa src + to string + .Fa dst . ++If ++.Fa src ++and ++.Fa dst ++overlap, behaviour is undefined. ++Applications in which ++.Fa src ++and ++.Fa dst ++might overlap should use ++.Xr memmove 3 ++instead. + .Sh RETURN VALUES + The + .Fn memcpy +@@ -75,17 +87,3 @@ + function + conforms to + .St -isoC . +-.Sh BUGS +-In this implementation +-.Fn memcpy +-is implemented using +-.Xr bcopy 3 , +-and therefore the strings may overlap. +-On other systems, copying overlapping strings may produce surprises. +-Programs intended to be portable should use +-.Xr memmove 3 +-when +-.Fa src +-and +-.Fa dst +-may overlap. diff --git a/string/FreeBSD/memcpy.c b/string/FreeBSD/memcpy.c new file mode 100644 index 0000000..dfc03ae --- /dev/null +++ b/string/FreeBSD/memcpy.c @@ -0,0 +1,5 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/memcpy.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + +#define MEMCOPY +#include "bcopy.c" diff --git a/string/FreeBSD/memcpy.c.patch b/string/FreeBSD/memcpy.c.patch new file mode 100644 index 0000000..4e60f56 --- /dev/null +++ b/string/FreeBSD/memcpy.c.patch @@ -0,0 +1,8 @@ +--- memcpy.c.orig Fri Mar 22 13:53:19 2002 ++++ memcpy.c Sat May 3 14:33:58 2003 +@@ -2,4 +2,4 @@ + __FBSDID("$FreeBSD: src/lib/libc/string/memcpy.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + + #define MEMCOPY +-#include "bcopy.c" ++#include "bcopy-fbsd.c" diff --git a/string/memmove.3 b/string/FreeBSD/memmove.3 similarity index 100% rename from string/memmove.3 rename to string/FreeBSD/memmove.3 diff --git a/string/FreeBSD/memmove.c b/string/FreeBSD/memmove.c new file mode 100644 index 0000000..8f44e82 --- /dev/null +++ b/string/FreeBSD/memmove.c @@ -0,0 +1,5 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/string/memmove.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + +#define MEMMOVE +#include "bcopy.c" diff --git a/string/FreeBSD/memmove.c.patch b/string/FreeBSD/memmove.c.patch new file mode 100644 index 0000000..1478a89 --- /dev/null +++ b/string/FreeBSD/memmove.c.patch @@ -0,0 +1,8 @@ +--- memmove.c.orig Fri Mar 22 13:53:19 2002 ++++ memmove.c Sat May 3 14:34:06 2003 +@@ -2,4 +2,4 @@ + __FBSDID("$FreeBSD: src/lib/libc/string/memmove.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + + #define MEMMOVE +-#include "bcopy.c" ++#include "bcopy-fbsd.c" diff --git a/string/memset.3 b/string/FreeBSD/memset.3 similarity index 100% rename from string/memset.3 rename to string/FreeBSD/memset.3 diff --git a/string/memset.c b/string/FreeBSD/memset.c similarity index 72% rename from string/memset.c rename to string/FreeBSD/memset.c index 84b9a30..1cb8644 100644 --- a/string/memset.c +++ b/string/FreeBSD/memset.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -61,41 +37,41 @@ #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 -#include #define wsize sizeof(u_int) #define wmask (wsize - 1) -#ifndef __ppc__ - #ifdef BZERO +#include + #define RETURN return #define VAL 0 #define WIDEVAL 0 void -bzero(dst0, length) - void *dst0; - register size_t length; +bzero(void *dst0, size_t length) #else +#include + #define RETURN return (dst0) #define VAL c0 #define WIDEVAL c void * -memset(dst0, c0, length) - void *dst0; - register int c0; - register size_t length; +memset(void *dst0, int c0, size_t length) #endif { - register size_t t; - register u_int c; - register u_char *dst; + size_t t; +#ifndef BZERO + u_int c; +#endif + u_char *dst; dst = dst0; /* @@ -110,7 +86,7 @@ memset(dst0, c0, length) * * 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; @@ -131,7 +107,7 @@ memset(dst0, c0, length) } #endif /* Align destination by filling in bytes. */ - if ((t = (int)dst & wmask) != 0) { + if ((t = (long)dst & wmask) != 0) { t = wsize - t; length -= t; do { @@ -154,4 +130,3 @@ memset(dst0, c0, length) } while (--t != 0); RETURN; } -#endif /* __ppc__ */ diff --git a/string/rindex.3 b/string/FreeBSD/rindex.3 similarity index 92% rename from string/rindex.3 rename to string/FreeBSD/rindex.3 index d7e5d89..2a2d1aa 100644 --- a/string/rindex.3 +++ b/string/FreeBSD/rindex.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)rindex.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/rindex.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $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 @@ -43,7 +43,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In strings.h .Ft char * .Fn rindex "const char *s" "int c" .Sh DESCRIPTION @@ -54,7 +54,7 @@ locates the last character matching .Fa c (converted to a -.Em char ) +.Vt char ) in the null-terminated string .Fa s . .Sh RETURN VALUES @@ -83,3 +83,10 @@ 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/rindex.c b/string/FreeBSD/rindex.c similarity index 61% rename from string/rindex.c rename to string/FreeBSD/rindex.c index 8028ae6..d33047a 100644 --- a/string/rindex.c +++ b/string/FreeBSD/rindex.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,23 +31,34 @@ * 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.5 2002/08/30 19:42:07 robert Exp $"); + #include + +#ifdef STRRCHR #include -/* consider #define rindex strrchr */ +char * +strrchr +#else +#include -char *strrchr(p, ch) - register const char *p; - register int ch; +char * +rindex +#endif +(const char *p, int ch) { - register char *save; + char *save; for (save = NULL;; ++p) { if (*p == ch) save = (char *)p; - if (!*p) - return(save); + if (*p == '\0') + return (save); } /* NOTREACHED */ } - diff --git a/string/FreeBSD/stpcpy.c b/string/FreeBSD/stpcpy.c new file mode 100644 index 0000000..2742bf7 --- /dev/null +++ b/string/FreeBSD/stpcpy.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.3 b/string/FreeBSD/strcasecmp.3 similarity index 92% rename from string/strcasecmp.3 rename to string/FreeBSD/strcasecmp.3 index f50cd5c..5f7a81c 100644 --- a/string/strcasecmp.3 +++ b/string/FreeBSD/strcasecmp.3 @@ -32,7 +32,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strcasecmp.3,v 1.9 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcasecmp.3,v 1.10 2002/08/30 15:40:01 robert Exp $ .\" .Dd June 9, 1993 .Dt STRCASECMP 3 @@ -44,7 +44,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In string.h +.In strings.h .Ft int .Fn strcasecmp "const char *s1" "const char *s2" .Ft int @@ -95,3 +95,10 @@ and .Fn strncasecmp functions first appeared in .Bx 4.4 . +Their prototypes existed previously in +.Aq Pa string.h +before they were moved to +.Aq Pa strings.h +for +.St -p1003.1-2001 +compliance. diff --git a/string/FreeBSD/strcasecmp.c b/string/FreeBSD/strcasecmp.c new file mode 100644 index 0000000..6f400d7 --- /dev/null +++ b/string/FreeBSD/strcasecmp.c @@ -0,0 +1,77 @@ +/* + * 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 +#include + +typedef unsigned char u_char; + +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + const u_char + *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + while (tolower(*us1) == tolower(*us2++)) + if (*us1++ == '\0') + return (0); + return (tolower(*us1) - tolower(*--us2)); +} + +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + size_t n; +{ + if (n != 0) { + const u_char + *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + do { + if (tolower(*us1) != tolower(*us2++)) + return (tolower(*us1) - tolower(*--us2)); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} diff --git a/string/FreeBSD/strcasestr.c b/string/FreeBSD/strcasestr.c new file mode 100644 index 0000000..dafcb79 --- /dev/null +++ b/string/FreeBSD/strcasestr.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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/string/strcasestr.c,v 1.3 2002/03/21 18:44:54 obrien Exp $"); + +#include +#include + +/* + * Find the first occurrence of find in s, ignore case. + */ +char * +strcasestr(s, find) + const char *s, *find; +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} diff --git a/string/FreeBSD/strcat.3 b/string/FreeBSD/strcat.3 new file mode 100644 index 0000000..7367895 --- /dev/null +++ b/string/FreeBSD/strcat.3 @@ -0,0 +1,164 @@ +.\" 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 +.Nd concatenate strings +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft char * +.Fn strcat "char * restrict s" "const char * restrict append" +.Ft char * +.Fn strncat "char * restrict s" "const char * restrict append" "size_t count" +.Sh DESCRIPTION +The +.Fn strcat +and +.Fn strncat +functions +append a copy of the null-terminated string +.Fa append +to the end of the null-terminated string +.Fa s , +then add a terminating +.Ql \e0 . +The string +.Fa s +must have sufficient space to hold the result. +.Pp +The +.Fn strncat +function +appends not more than +.Fa count +characters from +.Fa append , +and then adds a terminating +.Ql \e0 . +.Sh RETURN VALUES +The +.Fn strcat +and +.Fn strncat +functions +return the pointer +.Fa s . +.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 +.Rs +.%T "The FreeBSD Security Architecture" +.Re +(See +.Pa "/usr/share/doc/{to be decided}" . ) +.Sh STANDARDS +The +.Fn strcat +and +.Fn strncat +functions +conform to +.St -isoC . diff --git a/i386/gen/strcat.c b/string/FreeBSD/strcat.c similarity index 61% rename from i386/gen/strcat.c rename to string/FreeBSD/strcat.c index 13414c6..5d28c86 100644 --- a/i386/gen/strcat.c +++ b/string/FreeBSD/strcat.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,26 +31,20 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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(s, append) - register char *s; - register const char *append; +strcat(char * __restrict s, const char * __restrict append) { char *save = s; for (; *s; ++s); - while (*s++ = *append++); + while ((*s++ = *append++)); return(save); } - -#else -#warning ----------- Check for implementation of strcat() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/string/strchr.3 b/string/FreeBSD/strchr.3 similarity index 96% rename from string/strchr.3 rename to string/FreeBSD/strchr.3 index 97be859..6f8d3fa 100644 --- a/string/strchr.3 +++ b/string/FreeBSD/strchr.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strchr.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/strchr.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strchr.3,v 1.9 2002/12/18 13:33:03 ru Exp $ .\" .Dd April 19, 1994 .Dt STRCHR 3 @@ -52,9 +52,9 @@ The .Fn strchr function locates the first occurrence of -.Ar c +.Fa c in the string pointed to by -.Ar s . +.Fa s . The terminating .Dv NUL character is considered part of the string. diff --git a/string/FreeBSD/strchr.c b/string/FreeBSD/strchr.c new file mode 100644 index 0000000..2fb9114 --- /dev/null +++ b/string/FreeBSD/strchr.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.c" diff --git a/string/FreeBSD/strchr.c.patch b/string/FreeBSD/strchr.c.patch new file mode 100644 index 0000000..ed9a447 --- /dev/null +++ b/string/FreeBSD/strchr.c.patch @@ -0,0 +1,8 @@ +--- strchr.c.orig Fri Mar 22 13:53:19 2002 ++++ strchr.c Sat May 3 14:34:14 2003 +@@ -2,4 +2,4 @@ + __FBSDID("$FreeBSD: src/lib/libc/string/strchr.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + + #define STRCHR +-#include "index.c" ++#include "index-fbsd.c" diff --git a/string/strcmp.3 b/string/FreeBSD/strcmp.3 similarity index 100% rename from string/strcmp.3 rename to string/FreeBSD/strcmp.3 diff --git a/i386/gen/strcmp.c b/string/FreeBSD/strcmp.c similarity index 63% rename from i386/gen/strcmp.c rename to string/FreeBSD/strcmp.c index ffb7edf..1befcbc 100644 --- a/i386/gen/strcmp.c +++ b/string/FreeBSD/strcmp.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,12 @@ * SUCH DAMAGE. */ -#if !defined(hppa) && !defined(ppc) - #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ - #include +__FBSDID("$FreeBSD: src/lib/libc/string/strcmp.c,v 1.5 2002/03/21 18:44:54 obrien Exp $"); + #include /* @@ -72,14 +47,10 @@ static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93"; */ int strcmp(s1, s2) - register const char *s1, *s2; + const char *s1, *s2; { while (*s1 == *s2++) if (*s1++ == 0) return (0); - return (*(unsigned char *)s1 - *(unsigned char *)--s2); + return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); } - -#else -#warning ----------- Check for implementation of strcmp() ----------- ! -#endif /* !defined(hppa) */ diff --git a/string/strcoll.3 b/string/FreeBSD/strcoll.3 similarity index 96% rename from string/strcoll.3 rename to string/FreeBSD/strcoll.3 index 7617184..d2e1ae4 100644 --- a/string/strcoll.3 +++ b/string/FreeBSD/strcoll.3 @@ -34,7 +34,7 @@ .\" 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/strcoll.3,v 1.12 2002/10/15 10:11:53 tjr Exp $ .\" .Dd June 4, 1993 .Dt STRCOLL 3 @@ -66,7 +66,8 @@ is greater than, equal to, or less than .Sh SEE ALSO .Xr setlocale 3 , .Xr strcmp 3 , -.Xr strxfrm 3 +.Xr strxfrm 3 , +.Xr wcscoll 3 .Sh STANDARDS The .Fn strcoll diff --git a/string/FreeBSD/strcoll.c b/string/FreeBSD/strcoll.c new file mode 100644 index 0000000..b93ce48 --- /dev/null +++ b/string/FreeBSD/strcoll.c @@ -0,0 +1,86 @@ +/*- + * 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 +#include +#include "collate.h" + +int +strcoll(s, s2) + const char *s, *s2; +{ + int len, len2, prim, prim2, sec, sec2, ret, ret2; + const char *t, *t2; + char *tt, *tt2; + + if (__collate_load_error) + return strcmp(s, s2); + + len = len2 = 1; + ret = ret2 = 0; + if (__collate_substitute_nontrivial) { + t = tt = __collate_substitute(s); + t2 = tt2 = __collate_substitute(s2); + } else { + tt = tt2 = NULL; + t = s; + t2 = s2; + } + while(*t && *t2) { + prim = prim2 = 0; + while(*t && !prim) { + __collate_lookup(t, &len, &prim, &sec); + t += len; + } + while(*t2 && !prim2) { + __collate_lookup(t2, &len2, &prim2, &sec2); + 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); + else if(*t && !*t2) + ret = (u_char)*t; + else if(!*t && !*t2) + ret = ret2; + end: + free(tt); + free(tt2); + + return ret; +} diff --git a/string/strcpy.3 b/string/FreeBSD/strcpy.3 similarity index 77% rename from string/strcpy.3 rename to string/FreeBSD/strcpy.3 index 2a06447..138bace 100644 --- a/string/strcpy.3 +++ b/string/FreeBSD/strcpy.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcpy.3,v 1.11 2001/10/01 16:09:00 ru Exp $ +.\" $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 @@ -47,40 +47,48 @@ .Sh SYNOPSIS .In string.h .Ft char * -.Fn strcpy "char *dst" "const char *src" +.Fn stpcpy "char *dst" "const char *src" .Ft char * -.Fn strncpy "char *dst" "const char *src" "size_t len" +.Fn strcpy "char * restrict dst" "const char * restrict src" +.Ft char * +.Fn strncpy "char * restrict dst" "const char * restrict src" "size_t len" .Sh DESCRIPTION The +.Fn stpcpy +and .Fn strcpy -function -copies the string +functions +copy the string .Fa src to .Fa dst (including the terminating .Ql \e0 -character). +character.) .Pp The .Fn strncpy -function copies not more than +function copies at most .Fa len characters from .Fa src into -.Fa dst , -appending -.Ql \e0 -characters if +.Fa dst . +If .Fa src is less than .Fa len -characters long, and -.Em not -terminating +characters long, +the remainder of .Fa dst -otherwise. +is filled with +.Ql \e0 +characters. +Otherwise, +.Fa dst +is +.Em not +terminated. .Sh RETURN VALUES The .Fn strcpy @@ -89,6 +97,12 @@ and functions return .Fa dst . +The +.Fn stpcpy +function returns a pointer to the terminating +.Ql \e0 +character of +.Fa dst . .Sh EXAMPLES The following sets .Va chararray @@ -116,7 +130,7 @@ Note that it does terminate .Va chararray because the length of the source string is greater than or equal -to the length parameter. +to the length argument. .Pp The following copies as many characters from .Va input @@ -149,12 +163,27 @@ 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 +.Rs +.%T "The FreeBSD Security Architecture" +.Re +(See +.Pa "/usr/share/doc/{to be decided}" . ) .Sh STANDARDS The .Fn strcpy @@ -163,3 +192,16 @@ and 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/i386/gen/strcpy.c b/string/FreeBSD/strcpy.c similarity index 61% rename from i386/gen/strcpy.c rename to string/FreeBSD/strcpy.c index 2be8ae5..5cd2f45 100644 --- a/i386/gen/strcpy.c +++ b/string/FreeBSD/strcpy.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,26 +31,19 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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(to, from) - register char *to; - register const char *from; +strcpy(char * __restrict to, const char * __restrict from) { char *save = to; - for (; *to = *from; ++from, ++to); + for (; (*to = *from); ++from, ++to); return(save); } - -#else -#warning ----------- Check for implementation of strcpy() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/string/strcspn.3 b/string/FreeBSD/strcspn.3 similarity index 100% rename from string/strcspn.3 rename to string/FreeBSD/strcspn.3 diff --git a/string/strcspn.c b/string/FreeBSD/strcspn.c similarity index 67% rename from string/strcspn.c rename to string/FreeBSD/strcspn.c index cf1b44d..48354a6 100644 --- a/string/strcspn.c +++ b/string/FreeBSD/strcspn.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,8 +34,12 @@ * 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 $"); + #include /* @@ -68,10 +48,10 @@ size_t strcspn(s1, s2) const char *s1; - register const char *s2; + const char *s2; { - register const char *p, *spanp; - register char c, sc; + const char *p, *spanp; + char c, sc; /* * Stop as soon as we find any character from s2. Note that there diff --git a/string/strdup.3 b/string/FreeBSD/strdup.3 similarity index 100% rename from string/strdup.3 rename to string/FreeBSD/strdup.3 diff --git a/string/strdup.c b/string/FreeBSD/strdup.c similarity index 63% rename from string/strdup.c rename to string/FreeBSD/strdup.c index bee08fa..a9881a1 100644 --- a/string/strdup.c +++ b/string/FreeBSD/strdup.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,8 +31,11 @@ * SUCH DAMAGE. */ - -#include +#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 @@ -70,8 +49,8 @@ strdup(str) char *copy; len = strlen(str) + 1; - if (!(copy = malloc((u_int)len))) + if ((copy = malloc(len)) == NULL) return (NULL); - bcopy(str, copy, len); + memcpy(copy, str, len); return (copy); } diff --git a/string/strerror.3 b/string/FreeBSD/strerror.3 similarity index 73% rename from string/strerror.3 rename to string/FreeBSD/strerror.3 index c82aebf..1462c65 100644 --- a/string/strerror.3 +++ b/string/FreeBSD/strerror.3 @@ -34,14 +34,15 @@ .\" SUCH DAMAGE. .\" .\" @(#)strerror.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strerror.3,v 1.12 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strerror.3,v 1.22 2002/12/19 10:24:52 tjr Exp $ .\" -.Dd June 9, 1993 +.Dd December 19, 2002 .Dt STRERROR 3 .Os .Sh NAME .Nm perror , .Nm strerror , +.Nm strerror_r , .Nm sys_errlist , .Nm sys_nerr .Nd system error messages @@ -54,11 +55,14 @@ .Vt extern const char * const sys_errlist[] ; .Vt extern const int sys_nerr ; .In string.h -.Ft char * +.Ft "char *" .Fn strerror "int errnum" +.Ft int +.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen" .Sh DESCRIPTION The -.Fn strerror +.Fn strerror , +.Fn strerror_r and .Fn perror functions look up the error message string corresponding to an @@ -68,11 +72,18 @@ The .Fn strerror function accepts an error number argument .Fa errnum -and -returns a pointer to the corresponding +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 @@ -88,15 +99,41 @@ 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 Ql \&:\ \& ; +.Pq Dq Li ":\ " ; otherwise, only the error message string is printed. .Pp If .Fa errnum is not a recognized error number, -the error message string will contain +.Fn strerror +returns an error message string containing .Dq Li "Unknown error:\ " -followed by the error number in decimal. +followed by the error number in decimal, while +.Fn strerror_r +leaves +.Fa strerrbuf +unchanged and returns +.Er EINVAL . +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 @@ -107,10 +144,23 @@ 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 @@ -118,12 +168,23 @@ 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 diff --git a/string/FreeBSD/strerror.c b/string/FreeBSD/strerror.c new file mode 100644 index 0000000..71c514e --- /dev/null +++ b/string/FreeBSD/strerror.c @@ -0,0 +1,99 @@ +/*- + * 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.11 2003/01/03 16:44:42 mike 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)) + +/* + * 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) +{ + 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 < 1 || errnum >= sys_nerr) { + errstr(errnum, strerrbuf, buflen); + return (EINVAL); + } + if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) + return (ERANGE); + return (0); +} + +char * +strerror(int num) +{ + static char ebuf[EBUFSIZE]; + + if (num > 0 && num < sys_nerr) + return ((char *)sys_errlist[num]); + errno = EINVAL; + errstr(num, ebuf, sizeof(ebuf)); + return (ebuf); +} diff --git a/string/string.3 b/string/FreeBSD/string.3 similarity index 96% rename from string/string.3 rename to string/FreeBSD/string.3 index 04e84bb..0a59cec 100644 --- a/string/string.3 +++ b/string/FreeBSD/string.3 @@ -32,12 +32,13 @@ .\" SUCH DAMAGE. .\" .\" @(#)string.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/string/string.3,v 1.11 2001/10/01 16:09:00 ru Exp $ +.\" $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 stpcpy , .Nm strcat , .Nm strncat , .Nm strchr , @@ -64,6 +65,8 @@ .Sh SYNOPSIS .In string.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" @@ -120,6 +123,7 @@ for size limitations. .Xr bstring 3 , .Xr index 3 , .Xr rindex 3 , +.Xr stpcpy 3 , .Xr strcasecmp 3 , .Xr strcat 3 , .Xr strchr 3 , @@ -147,7 +151,6 @@ The .Fn strerror , .Fn strlen , .Fn strpbrk , -.Fn strsep , .Fn strspn , .Fn strcspn , .Fn strstr , diff --git a/string/strlcat.c b/string/FreeBSD/strlcat.c similarity index 85% rename from string/strlcat.c rename to string/FreeBSD/strlcat.c index 7ec53b1..1c52972 100644 --- a/string/strlcat.c +++ b/string/FreeBSD/strlcat.c @@ -1,3 +1,5 @@ +/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */ + /* * Copyright (c) 1998 Todd C. Miller * All rights reserved. @@ -26,12 +28,10 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; +static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"); #endif /* LIBC_SCCS and not lint */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strlcat.c,v 1.2.4.2 2001/07/09 23:30:06 obrien Exp $"; -#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/string/strlcat.c,v 1.7 2002/03/21 18:44:54 obrien Exp $"); #include #include @@ -40,17 +40,18 @@ static const char rcsid[] = * 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(initial dst) + strlen(src); if retval >= siz, - * truncation occurred. + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. */ -size_t strlcat(dst, src, siz) +size_t +strlcat(dst, src, siz) char *dst; const char *src; size_t siz; { - register char *d = dst; - register const char *s = src; - register size_t n = 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 */ diff --git a/string/strlcpy.3 b/string/FreeBSD/strlcpy.3 similarity index 98% rename from string/strlcpy.3 rename to string/FreeBSD/strlcpy.3 index 60bb36b..974cd95 100644 --- a/string/strlcpy.3 +++ b/string/FreeBSD/strlcpy.3 @@ -25,7 +25,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.11 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.12 2002/12/18 12:45:11 ru Exp $ .\" .Dd June 22, 1998 .Dt STRLCPY 3 @@ -192,6 +192,7 @@ As a matter of fact, the first version of this manual page got it wrong. .Xr strncat 3 , .Xr strncpy 3 .Sh HISTORY +The .Fn strlcpy and .Fn strlcat diff --git a/string/strlcpy.c b/string/FreeBSD/strlcpy.c similarity index 90% rename from string/strlcpy.c rename to string/FreeBSD/strlcpy.c index 9de9d32..0d21c23 100644 --- a/string/strlcpy.c +++ b/string/FreeBSD/strlcpy.c @@ -28,14 +28,10 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; -#endif +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"); #endif /* LIBC_SCCS and not lint */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.2.4.1 2001/07/09 23:30:06 obrien Exp $"; -#endif +#include +__FBSDID("$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.5 2002/03/21 18:44:54 obrien Exp $"); #include #include @@ -50,9 +46,9 @@ size_t strlcpy(dst, src, siz) const char *src; size_t siz; { - register char *d = dst; - register const char *s = src; - register size_t n = siz; + char *d = dst; + const char *s = src; + size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { diff --git a/string/strlen.3 b/string/FreeBSD/strlen.3 similarity index 100% rename from string/strlen.3 rename to string/FreeBSD/strlen.3 diff --git a/i386/gen/strlen.c b/string/FreeBSD/strlen.c similarity index 63% rename from i386/gen/strlen.c rename to string/FreeBSD/strlen.c index 35e83f0..c67667d 100644 --- a/i386/gen/strlen.c +++ b/string/FreeBSD/strlen.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,26 +31,21 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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; { - register const char *s; + const char *s; for (s = str; *s; ++s); return(s - str); } -#else -#warning ----------- Check for implementation of strlen() ----------- ! -#endif /* !defined(__ppc__) */ - diff --git a/string/strmode.3 b/string/FreeBSD/strmode.3 similarity index 100% rename from string/strmode.3 rename to string/FreeBSD/strmode.3 diff --git a/string/strmode.c b/string/FreeBSD/strmode.c similarity index 76% rename from string/strmode.c rename to string/FreeBSD/strmode.c index 41fb14e..2409b4e 100644 --- a/string/strmode.c +++ b/string/FreeBSD/strmode.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,6 +31,11 @@ * 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 @@ -62,8 +43,8 @@ void strmode(mode, p) - register mode_t mode; - register char *p; + mode_t mode; + char *p; { /* print type */ switch (mode & S_IFMT) { diff --git a/i386/gen/strncat.c b/string/FreeBSD/strncat.c similarity index 64% rename from i386/gen/strncat.c rename to string/FreeBSD/strncat.c index cf15150..e05e030 100644 --- a/i386/gen/strncat.c +++ b/string/FreeBSD/strncat.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,12 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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 /* @@ -72,14 +47,11 @@ static char sccsid[] = "@(#)strncat.c 8.1 (Berkeley) 6/4/93"; * are written at dst (at most n+1 bytes being appended). Return dst. */ char * -strncat(dst, src, n) - char *dst; - const char *src; - register size_t n; +strncat(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { - register char *d = dst; - register const char *s = src; + char *d = dst; + const char *s = src; while (*d != 0) d++; @@ -92,7 +64,3 @@ strncat(dst, src, n) } return (dst); } - -#else -#warning ----------- Check for implementation of strncat() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/i386/gen/strncmp.c b/string/FreeBSD/strncmp.c similarity index 62% rename from i386/gen/strncmp.c rename to string/FreeBSD/strncmp.c index 1294b19..6b0cfc8 100644 --- a/i386/gen/strncmp.c +++ b/string/FreeBSD/strncmp.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,32 +31,28 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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) - register const char *s1, *s2; - register size_t n; + const char *s1, *s2; + size_t n; { if (n == 0) return (0); do { if (*s1 != *s2++) - return (*(unsigned char *)s1 - *(unsigned char *)--s2); + return (*(const unsigned char *)s1 - + *(const unsigned char *)(s2 - 1)); if (*s1++ == 0) break; } while (--n != 0); return (0); } - -#else -#warning ----------- Check for implementation of strncmp() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/i386/gen/strncpy.c b/string/FreeBSD/strncpy.c similarity index 64% rename from i386/gen/strncpy.c rename to string/FreeBSD/strncpy.c index 8b0414a..2fcc957 100644 --- a/i386/gen/strncpy.c +++ b/string/FreeBSD/strncpy.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,13 +34,12 @@ * SUCH DAMAGE. */ -#if !defined(__ppc__) - #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 /* @@ -72,14 +47,11 @@ static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93"; * Return dst. */ char * -strncpy(dst, src, n) - char *dst; - const char *src; - register size_t n; +strncpy(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { - register char *d = dst; - register const char *s = src; + char *d = dst; + const char *s = src; do { if ((*d++ = *s++) == 0) { @@ -92,7 +64,3 @@ strncpy(dst, src, n) } return (dst); } - -#else -#warning ----------- Check for implementation of strncpy() ----------- ! -#endif /* !defined(__ppc__) */ diff --git a/string/FreeBSD/strnstr.c b/string/FreeBSD/strnstr.c new file mode 100644 index 0000000..9f3b038 --- /dev/null +++ b/string/FreeBSD/strnstr.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.2 2001/11/07 19:55:16 obrien 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 ((sc = *s++) == '\0' || slen-- < 1) + 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.3 b/string/FreeBSD/strpbrk.3 similarity index 100% rename from string/strpbrk.3 rename to string/FreeBSD/strpbrk.3 diff --git a/string/strpbrk.c b/string/FreeBSD/strpbrk.c similarity index 65% rename from string/strpbrk.c rename to string/FreeBSD/strpbrk.c index 1c9032f..fb0e1d4 100644 --- a/string/strpbrk.c +++ b/string/FreeBSD/strpbrk.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,8 +31,12 @@ * 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 /* @@ -64,10 +44,10 @@ */ char * strpbrk(s1, s2) - register const char *s1, *s2; + const char *s1, *s2; { - register const char *scanp; - register int c, sc; + const char *scanp; + int c, sc; while ((c = *s1++) != 0) { for (scanp = s2; (sc = *scanp++) != 0;) diff --git a/string/strrchr.3 b/string/FreeBSD/strrchr.3 similarity index 100% rename from string/strrchr.3 rename to string/FreeBSD/strrchr.3 diff --git a/string/FreeBSD/strrchr.c b/string/FreeBSD/strrchr.c new file mode 100644 index 0000000..b8c0500 --- /dev/null +++ b/string/FreeBSD/strrchr.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.c" diff --git a/string/FreeBSD/strrchr.c.patch b/string/FreeBSD/strrchr.c.patch new file mode 100644 index 0000000..d31740f --- /dev/null +++ b/string/FreeBSD/strrchr.c.patch @@ -0,0 +1,8 @@ +--- strrchr.c.orig Fri Mar 22 13:53:19 2002 ++++ strrchr.c Sat May 3 14:34:24 2003 +@@ -2,4 +2,4 @@ + __FBSDID("$FreeBSD: src/lib/libc/string/strrchr.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); + + #define STRRCHR +-#include "rindex.c" ++#include "rindex-fbsd.c" diff --git a/string/strsep.3 b/string/FreeBSD/strsep.3 similarity index 93% rename from string/strsep.3 rename to string/FreeBSD/strsep.3 index 3b5e3bc..0218aea 100644 --- a/string/strsep.3 +++ b/string/FreeBSD/strsep.3 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strsep.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/string/strsep.3,v 1.11 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strsep.3,v 1.13 2002/11/29 15:57:49 ru Exp $ .\" .Dd June 9, 1993 .Dt STRSEP 3 @@ -65,10 +65,13 @@ The original value of .Fa *stringp is returned. .Pp -An ``empty'' field, i.e. one caused by two adjacent delimiter characters, -can be detected by comparing the location referenced by the pointer returned -in -.Fa *stringp +An +.Dq empty +field (i.e., a character in the string +.Fa delim +occurs as the first character of +.Fa *stringp ) +can be detected by comparing the location referenced by the returned pointer to .Ql \e0 . .Pp diff --git a/string/strsep.c b/string/FreeBSD/strsep.c similarity index 69% rename from string/strsep.c rename to string/FreeBSD/strsep.c index 9139dd3..d0bccce 100644 --- a/string/strsep.c +++ b/string/FreeBSD/strsep.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -55,17 +31,18 @@ * SUCH DAMAGE. */ -#include -#include -#include - #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. + * 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. @@ -76,12 +53,12 @@ static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; */ char * strsep(stringp, delim) - register char **stringp; - register const char *delim; + char **stringp; + const char *delim; { - register char *s; - register const char *spanp; - register int c, sc; + char *s; + const char *spanp; + int c, sc; char *tok; if ((s = *stringp) == NULL) diff --git a/string/FreeBSD/strsignal.c b/string/FreeBSD/strsignal.c new file mode 100644 index 0000000..0cbb4cd --- /dev/null +++ b/string/FreeBSD/strsignal.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 < sys_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/FreeBSD/strsignal.c.patch b/string/FreeBSD/strsignal.c.patch new file mode 100644 index 0000000..378e74d --- /dev/null +++ b/string/FreeBSD/strsignal.c.patch @@ -0,0 +1,11 @@ +--- strsignal.c.orig Thu Mar 21 10:44:54 2002 ++++ strsignal.c Thu May 8 00:44:31 2003 +@@ -52,7 +52,7 @@ + char tmp[40]; + + signum = num; /* convert to unsigned */ +- if (signum < sys_nsig) ++ if (signum < NSIG) + return ((char *)sys_siglist[signum]); + + /* Do this by hand, so we don't link to stdio(3). */ diff --git a/string/strspn.3 b/string/FreeBSD/strspn.3 similarity index 100% rename from string/strspn.3 rename to string/FreeBSD/strspn.3 diff --git a/string/strspn.c b/string/FreeBSD/strspn.c similarity index 65% rename from string/strspn.c rename to string/FreeBSD/strspn.c index e678b03..ae28642 100644 --- a/string/strspn.c +++ b/string/FreeBSD/strspn.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -55,8 +31,12 @@ * 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 $"); + #include /* @@ -65,10 +45,10 @@ size_t strspn(s1, s2) const char *s1; - register const char *s2; + const char *s2; { - register const char *p = s1, *spanp; - register char c, sc; + const char *p = s1, *spanp; + char c, sc; /* * Skip any characters in s2, excluding the terminating \0. diff --git a/string/strstr.3 b/string/FreeBSD/strstr.3 similarity index 94% rename from string/strstr.3 rename to string/FreeBSD/strstr.3 index 433f26c..83d7bed 100644 --- a/string/strstr.3 +++ b/string/FreeBSD/strstr.3 @@ -35,7 +35,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strstr.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strstr.3,v 1.11 2001/10/11 15:49:06 mike Exp $ +.\" $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 @@ -85,7 +85,7 @@ Since the .Fn strnstr function is a .Fx -specific API, it should only be used when portablility is not a concern. +specific API, it should only be used when portability is not a concern. .Sh RETURN VALUES If .Fa little @@ -96,7 +96,8 @@ if .Fa little occurs nowhere in .Fa big , -NULL is returned; +.Dv NULL +is returned; otherwise a pointer to the first character of the first occurrence of .Fa little is returned. @@ -104,7 +105,7 @@ is returned. The following sets the pointer .Va ptr to the -.Dq Li Bar Baz +.Qq Li Bar Baz portion of .Va largestring : .Bd -literal -offset indent @@ -117,7 +118,9 @@ ptr = strstr(largestring, smallstring); .Pp The following sets the pointer .Va ptr -to NULL, because only the first 4 characters of +to +.Dv NULL , +because only the first 4 characters of .Va largestring are searched: .Bd -literal -offset indent diff --git a/string/strstr.c b/string/FreeBSD/strstr.c similarity index 66% rename from string/strstr.c rename to string/FreeBSD/strstr.c index ec11245..f51d170 100644 --- a/string/strstr.c +++ b/string/FreeBSD/strstr.c @@ -1,28 +1,4 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. * @@ -58,8 +34,12 @@ * 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 /* @@ -67,10 +47,10 @@ */ char * strstr(s, find) - register const char *s, *find; + const char *s, *find; { - register char c, sc; - register size_t len; + char c, sc; + size_t len; if ((c = *find++) != 0) { len = strlen(find); diff --git a/string/strtok.3 b/string/FreeBSD/strtok.3 similarity index 97% rename from string/strtok.3 rename to string/FreeBSD/strtok.3 index bc90987..b1d41b9 100644 --- a/string/strtok.3 +++ b/string/FreeBSD/strtok.3 @@ -48,7 +48,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strtok.3 8.2 (Berkeley) 2/3/94 -.\" $FreeBSD: src/lib/libc/string/strtok.3,v 1.22 2001/10/01 16:09:00 ru Exp $ +.\" $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 @@ -98,7 +98,9 @@ function is a reentrant version of 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 @@ -145,7 +147,8 @@ for (word = strtok_r(test, sep, &brkt); .Xr strrchr 3 , .Xr strsep 3 , .Xr strspn 3 , -.Xr strstr 3 +.Xr strstr 3 , +.Xr wcstok 3 .Sh STANDARDS The .Fn strtok diff --git a/string/strtok.c b/string/FreeBSD/strtok.c similarity index 53% rename from string/strtok.c rename to string/FreeBSD/strtok.c index 1dfa6ad..6aec194 100644 --- a/string/strtok.c +++ b/string/FreeBSD/strtok.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1998 Softweyr LLC. All rights reserved. * * strtok_r, from Berkeley strtok @@ -10,20 +10,15 @@ * Redistribution and use in source and binary 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. @@ -41,128 +36,105 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strtok.c,v 1.2.6.1 2001/07/09 23:30:07 obrien Exp $"; -#endif +#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) +__strtok_r(char *s, const char *delim, char **last) { - char *spanp; - int c, sc; - char *tok; - - if (s == NULL && (s = *last) == NULL) - { - return NULL; - } - - /* - * Skip (span) leading delimiters (s += strspn(s, delim), sort of). - */ + 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 - { - char *w = s - 1; - *w = '\0'; - } - *last = s; - return tok; - } + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; } - while (sc != 0); - } - /* NOTREACHED */ -} + 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; + static char *last; - return strtok_r(s, delim, &last); + return (__strtok_r(s, delim, &last)); } - -#if defined(DEBUG_STRTOK) - +#ifdef DEBUG_STRTOK /* * Test the tokenizer. */ int -main() +main(void) { - char test[80], blah[80]; - char *sep = "\\/:;=-"; - char *word, *phrase, *brkt, *brkb; - - 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); - } + char blah[80], test[80]; + char *brkb, *brkt, *phrase, *sep, *word; - phrase = "foo"; + sep = "\\/:;=-"; + phrase = "foo"; - strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function."); + 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 (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); + 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; + return (0); } #endif /* DEBUG_STRTOK */ diff --git a/string/strxfrm.3 b/string/FreeBSD/strxfrm.3 similarity index 94% rename from string/strxfrm.3 rename to string/FreeBSD/strxfrm.3 index f291222..14b6bbc 100644 --- a/string/strxfrm.3 +++ b/string/FreeBSD/strxfrm.3 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strxfrm.3,v 1.14 2001/10/01 16:09:00 ru Exp $ +.\" $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 @@ -47,7 +47,7 @@ .Sh SYNOPSIS .In string.h .Ft size_t -.Fn strxfrm "char *dst" "const char *src" "size_t n" +.Fn strxfrm "char * restrict dst" "const char * restrict src" "size_t n" .Sh DESCRIPTION The .Fn strxfrm @@ -90,7 +90,8 @@ are indeterminate. .Sh SEE ALSO .Xr setlocale 3 , .Xr strcmp 3 , -.Xr strcoll 3 +.Xr strcoll 3 , +.Xr wcsxfrm 3 .Sh STANDARDS The .Fn strxfrm diff --git a/string/FreeBSD/strxfrm.c b/string/FreeBSD/strxfrm.c new file mode 100644 index 0000000..3ab7b72 --- /dev/null +++ b/string/FreeBSD/strxfrm.c @@ -0,0 +1,83 @@ +/*- + * 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 +#include +#include "collate.h" + +size_t +strxfrm(char * __restrict dest, const char * __restrict src, size_t len) +{ + int prim, sec, l; + size_t slen; + char *s, *ss; + + if (!*src) { + if (len > 0) + *dest = '\0'; + return 0; + } + + if (__collate_load_error) { + slen = strlen(src); + if (len > 0) { + if (slen < len) + strcpy(dest, src); + else { + strncpy(dest, src, len - 1); + dest[len - 1] = '\0'; + } + } + return slen; + } + + slen = 0; + prim = sec = 0; + ss = s = __collate_substitute(src); + while (*s) { + while (*s && !prim) { + __collate_lookup(s, &l, &prim, &sec); + s += l; + } + if (prim) { + if (len > 1) { + *dest++ = (char)prim; + len--; + } + slen++; + prim = 0; + } + } + free(ss); + if (len > 0) + *dest = '\0'; + + return slen; +} diff --git a/string/swab.3 b/string/FreeBSD/swab.3 similarity index 93% rename from string/swab.3 rename to string/FreeBSD/swab.3 index fffd7cd..c449add 100644 --- a/string/swab.3 +++ b/string/FreeBSD/swab.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)swab.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/swab.3,v 1.6 2001/10/01 16:09:00 ru Exp $ +.\" $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 @@ -43,7 +43,7 @@ .Sh SYNOPSIS .In string.h .Ft void -.Fn swab "const void *src" "void *dst" "size_t len" +.Fn swab "const void * restrict src" "void * restrict dst" "size_t len" .Sh DESCRIPTION The function .Fn swab diff --git a/string/swab.c b/string/FreeBSD/swab.c similarity index 62% rename from string/swab.c rename to string/FreeBSD/swab.c index 3e59c71..de57703 100644 --- a/string/swab.c +++ b/string/FreeBSD/swab.c @@ -1,27 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. @@ -58,28 +34,29 @@ * 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(from, to, len) - const void *from; - void *to; - size_t len; +swab(const void * __restrict from, void * __restrict to, size_t len) { - register unsigned long temp; - register int n; - register char *fp, *tp; + unsigned long temp; + int n; + char *fp, *tp; - n = (len >> 1) + 1; + n = len >> 1; fp = (char *)from; tp = (char *)to; #define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp /* round to multiple of 8 */ - while ((--n) & 07) + for (; n & 0x7; --n) STEP; - n >>= 3; - while (--n >= 0) { + for (n >>= 3; n > 0; --n) { STEP; STEP; STEP; STEP; STEP; STEP; STEP; STEP; } diff --git a/string/FreeBSD/wcscat.c b/string/FreeBSD/wcscat.c new file mode 100644 index 0000000..cf7812f --- /dev/null +++ b/string/FreeBSD/wcscat.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/FreeBSD/wcschr.c b/string/FreeBSD/wcschr.c new file mode 100644 index 0000000..0fae132 --- /dev/null +++ b/string/FreeBSD/wcschr.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/FreeBSD/wcscmp.c b/string/FreeBSD/wcscmp.c new file mode 100644 index 0000000..20152b2 --- /dev/null +++ b/string/FreeBSD/wcscmp.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/FreeBSD/wcscoll.3 b/string/FreeBSD/wcscoll.3 new file mode 100644 index 0000000..18a9ef7 --- /dev/null +++ b/string/FreeBSD/wcscoll.3 @@ -0,0 +1,112 @@ +.\" 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 +.Nd compare wide strings according to current collation +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fn wcscoll "const wchar_t *s1" "const wchar_t *s2" +.Sh DESCRIPTION +The +.Fn wcscoll +function compares the null-terminated strings +.Fa s1 +and +.Fa s2 +according to the current locale collation order. +In the +.Dq Li C +locale, +.Fn wcscoll +is equivalent to +.Fn wcscmp . +.Sh RETURN VALUES +The +.Fn wcscoll +function +returns an integer greater than, equal to, or less than 0, +if +.Fa s1 +is greater than, equal to, or less than +.Fa s2 . +.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 +.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/FreeBSD/wcscoll.c b/string/FreeBSD/wcscoll.c new file mode 100644 index 0000000..3ffb8f0 --- /dev/null +++ b/string/FreeBSD/wcscoll.c @@ -0,0 +1,97 @@ +/*- + * 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.1 2002/10/04 03:18:26 tjr Exp $"); + +#include +#include +#include +#include +#include "collate.h" + +static char *__mbsdup(const wchar_t *); + +/* + * 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) +{ + char *mbs1, *mbs2; + int diff, sverrno; + + if (__collate_load_error || MB_CUR_MAX > 1) + /* + * Locale has no special collating order, could not be + * loaded, or has an extended character set; do a fast binary + * comparison. + */ + return (wcscmp(ws1, ws2)); + + if ((mbs1 = __mbsdup(ws1)) == NULL || (mbs2 = __mbsdup(ws2)) == NULL) { + /* + * 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)); + } + + diff = strcoll(mbs1, mbs2); + sverrno = errno; + free(mbs1); + free(mbs2); + errno = sverrno; + + return (diff); +} + +static char * +__mbsdup(const wchar_t *ws) +{ + mbstate_t state; + const wchar_t *wcp; + size_t len; + char *mbs; + + memset(&state, 0, sizeof(state)); + wcp = ws; + if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) + return (NULL); + if ((mbs = malloc(len + 1)) == NULL) + return (NULL); + memset(&state, 0, sizeof(state)); + wcsrtombs(mbs, &ws, len + 1, &state); + + return (mbs); +} diff --git a/string/FreeBSD/wcscpy.c b/string/FreeBSD/wcscpy.c new file mode 100644 index 0000000..b4c236a --- /dev/null +++ b/string/FreeBSD/wcscpy.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/FreeBSD/wcscspn.c b/string/FreeBSD/wcscspn.c new file mode 100644 index 0000000..c16f270 --- /dev/null +++ b/string/FreeBSD/wcscspn.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/FreeBSD/wcslcat.c b/string/FreeBSD/wcslcat.c new file mode 100644 index 0000000..f3b9a63 --- /dev/null +++ b/string/FreeBSD/wcslcat.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/FreeBSD/wcslcpy.c b/string/FreeBSD/wcslcpy.c new file mode 100644 index 0000000..273c8fd --- /dev/null +++ b/string/FreeBSD/wcslcpy.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/FreeBSD/wcslen.c b/string/FreeBSD/wcslen.c new file mode 100644 index 0000000..5e462a1 --- /dev/null +++ b/string/FreeBSD/wcslen.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/FreeBSD/wcsncat.c b/string/FreeBSD/wcsncat.c new file mode 100644 index 0000000..5abb442 --- /dev/null +++ b/string/FreeBSD/wcsncat.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/FreeBSD/wcsncmp.c b/string/FreeBSD/wcsncmp.c new file mode 100644 index 0000000..7043e06 --- /dev/null +++ b/string/FreeBSD/wcsncmp.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/FreeBSD/wcsncpy.c b/string/FreeBSD/wcsncpy.c new file mode 100644 index 0000000..fb9cef0 --- /dev/null +++ b/string/FreeBSD/wcsncpy.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/FreeBSD/wcspbrk.c b/string/FreeBSD/wcspbrk.c new file mode 100644 index 0000000..5502440 --- /dev/null +++ b/string/FreeBSD/wcspbrk.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/FreeBSD/wcsrchr.c b/string/FreeBSD/wcsrchr.c new file mode 100644 index 0000000..093dd08 --- /dev/null +++ b/string/FreeBSD/wcsrchr.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/FreeBSD/wcsspn.c b/string/FreeBSD/wcsspn.c new file mode 100644 index 0000000..d4101c7 --- /dev/null +++ b/string/FreeBSD/wcsspn.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/FreeBSD/wcsstr.c b/string/FreeBSD/wcsstr.c new file mode 100644 index 0000000..0533e59 --- /dev/null +++ b/string/FreeBSD/wcsstr.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/FreeBSD/wcstok.3 b/string/FreeBSD/wcstok.3 new file mode 100644 index 0000000..4ddfb04 --- /dev/null +++ b/string/FreeBSD/wcstok.3 @@ -0,0 +1,133 @@ +.\" 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 * +.Fn wcstok "wchar_t * restrict str" "const wchar_t * restrict sep" "wchar_t ** restrict last" +.Sh DESCRIPTION +The +.Fn wcstok +function +is used to isolate sequential tokens in a null-terminated wide character +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 wcstok +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. +The context pointer +.Fa last +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 and writes the 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 last , +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/string/FreeBSD/wcstok.c b/string/FreeBSD/wcstok.c new file mode 100644 index 0000000..5781adb --- /dev/null +++ b/string/FreeBSD/wcstok.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/gen/rfork_thread.3 b/string/FreeBSD/wcswidth.3 similarity index 54% rename from gen/rfork_thread.3 rename to string/FreeBSD/wcswidth.3 index 3d78998..973bfe0 100644 --- a/gen/rfork_thread.3 +++ b/string/FreeBSD/wcswidth.3 @@ -1,5 +1,4 @@ -.\" -.\" Copyright (c) 2000 Peter Wemm +.\" Copyright (c) 2002 Tim J. Robbins .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,55 +22,41 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/gen/rfork_thread.3,v 1.5 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/wcswidth.3,v 1.2 2002/12/09 14:04:05 ru Exp $ .\" -.Dd July 29, 2000 -.Dt RFORK_THREAD 3 +.Dd August 20, 2002 +.Dt WCSWIDTH 3 .Os .Sh NAME -.Nm rfork_thread -.Nd create a rfork-based process thread +.Nm wcswidth +.Nd "number of column positions in wide-character string" .Sh LIBRARY .Lb libc .Sh SYNOPSIS -.In unistd.h +.In wchar.h .Ft int -.Fn rfork_thread "int flags" "void *stack" "int (*func)(void *arg)" "void *arg" +.Fn wcswidth "const wchar_t *pwcs" "size_t n" .Sh DESCRIPTION -.Fn rfork_thread -is a helper function for -.Xr rfork 2 . -It arranges for a new process to be created and the child process will -call the specified function with the specified argument, while running on -the supplied stack. -.Pp -Using this function should avoid the need to implement complex stack -swap code. +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. .Sh RETURN VALUES -Upon successful completion, -.Fn rfork_thread -returns the process ID of the child process to the parent process. -Otherwise, a value of -1 is returned -to the parent process, no child process is created, and the global -variable -.Va errno -is set to indicate the error. -.Pp -The child process context is not aware of a return from the -.Fn rfork_thread -function as it begins executing directly with the supplied function. -.Sh ERRORS -See -.Xr rfork 2 -for error return codes. +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 fork 2 , -.Xr intro 2 , -.Xr minherit 2 , -.Xr rfork 2 , -.Xr vfork 2 -.Sh HISTORY +.Xr iswprint 3 , +.Xr wcwidth 3 +.Sh STANDARDS The -.Fn rfork_thread -function call first appeared in -.Fx 4.3 . +.Fn wcswidth +function conforms to +.St -p1003.1-2001 . diff --git a/string/FreeBSD/wcswidth.c b/string/FreeBSD/wcswidth.c new file mode 100644 index 0000000..98a095d --- /dev/null +++ b/string/FreeBSD/wcswidth.c @@ -0,0 +1,61 @@ +/* + * 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/string/wcswidth.c,v 1.6 2002/08/20 02:06:28 ache Exp $"); + +#include + +int +wcswidth(const wchar_t *pwcs, size_t n) +{ + wchar_t wc; + int len, l; + + len = 0; + while (n-- > 0 && (wc = *pwcs++) != L'\0') { + if ((l = wcwidth(wc)) < 0) + return (-1); + len += l; + } + return (len); +} + diff --git a/string/FreeBSD/wcsxfrm.3 b/string/FreeBSD/wcsxfrm.3 new file mode 100644 index 0000000..e85ebb0 --- /dev/null +++ b/string/FreeBSD/wcsxfrm.3 @@ -0,0 +1,126 @@ +.\" 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 +.Nd transform a wide string under locale +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fn wcsxfrm "wchar_t * restrict dst" "const wchar_t * restrict src" "size_t n" +.Sh DESCRIPTION +The +.Fn wcsxfrm +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 . +No more than +.Fa n +wide characters are copied into +.Fa dst , +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 +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 . +.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 dst +are indeterminate. +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strxfrm 3 , +.Xr wcscmp 3 , +.Xr wcscoll 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 dst , +whereas +.Fn wcscoll +compares characters using both primary and secondary weights. diff --git a/string/FreeBSD/wcsxfrm.c b/string/FreeBSD/wcsxfrm.c new file mode 100644 index 0000000..d0282c3 --- /dev/null +++ b/string/FreeBSD/wcsxfrm.c @@ -0,0 +1,115 @@ +/*- + * 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.1 2002/10/04 03:18:26 tjr Exp $"); + +#include +#include +#include +#include "collate.h" + +static char *__mbsdup(const wchar_t *); + +/* + * 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) +{ + int prim, sec, l; + size_t slen; + char *mbsrc, *s, *ss; + + if (*src == L'\0') { + if (len != 0) + *dest = L'\0'; + return (0); + } + + if (__collate_load_error || MB_CUR_MAX > 1) { + 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); + } + + mbsrc = __mbsdup(src); + slen = 0; + prim = sec = 0; + ss = s = __collate_substitute(mbsrc); + while (*s != '\0') { + while (*s != '\0' && prim == 0) { + __collate_lookup(s, &l, &prim, &sec); + s += l; + } + if (prim != 0) { + if (len > 1) { + *dest++ = (wchar_t)prim; + len--; + } + slen++; + prim = 0; + } + } + free(ss); + free(mbsrc); + if (len != 0) + *dest = L'\0'; + + return (slen); +} + +static char * +__mbsdup(const wchar_t *ws) +{ + mbstate_t state; + const wchar_t *wcp; + size_t len; + char *mbs; + + memset(&state, 0, sizeof(state)); + wcp = ws; + if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) + return (NULL); + if ((mbs = malloc(len + 1)) == NULL) + return (NULL); + memset(&state, 0, sizeof(state)); + wcsrtombs(mbs, &ws, len + 1, &state); + + return (mbs); +} diff --git a/string/wmemchr.3 b/string/FreeBSD/wmemchr.3 similarity index 89% rename from string/wmemchr.3 rename to string/FreeBSD/wmemchr.3 index cb41fc2..de091a6 100644 --- a/string/wmemchr.3 +++ b/string/FreeBSD/wmemchr.3 @@ -37,7 +37,7 @@ .\" .\" from: @(#)strcpy.3 8.1 (Berkeley) 6/4/93 .\" -.\" $FreeBSD: src/lib/libc/string/wmemchr.3,v 1.5 2001/10/03 05:19:47 bde Exp $ +.\" $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 @@ -73,19 +73,19 @@ .Ft int .Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft wchar_t * -.Fn wmemcpy "wchar_t *s1" "const wchar_t *s2" "size_t n" +.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 *s1" "const wchar_t *s2" +.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 *s1" "const wchar_t *s2" +.Fn wcscpy "wchar_t * restrict s1" "const wchar_t * restrict s2" .Ft size_t .Fn wcscspn "const wchar_t *s1" "const wchar_t *s2" .Ft size_t @@ -95,11 +95,11 @@ .Ft size_t .Fn wcslen "const wchar_t *s" .Ft wchar_t * -.Fn wcsncat "wchar_t *s1" "const wchar_t *s2" "size_t n" +.Fn wcsncat "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" .Ft int .Fn wcsncmp "const wchar_t *s1" "const wchar_t * s2" "size_t n" .Ft wchar_t * -.Fn wcsncpy "wchar_t *s1" "const wchar_t *s2" "size_t n" +.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 * @@ -107,7 +107,7 @@ .Ft size_t .Fn wcsspn "const wchar_t *s1" "const wchar_t *s2" .Ft wchar_t * -.Fn wcsstr "const wchar_t *s1" "const wchar_t *s2" +.Fn wcsstr "const wchar_t * restrict s1" "const wchar_t * restrict s2" .Sh DESCRIPTION The functions implement string manipulation operations over wide character strings. diff --git a/string/FreeBSD/wmemchr.c b/string/FreeBSD/wmemchr.c new file mode 100644 index 0000000..0b09f94 --- /dev/null +++ b/string/FreeBSD/wmemchr.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/FreeBSD/wmemcmp.c b/string/FreeBSD/wmemcmp.c new file mode 100644 index 0000000..3014041 --- /dev/null +++ b/string/FreeBSD/wmemcmp.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/FreeBSD/wmemcpy.c b/string/FreeBSD/wmemcpy.c new file mode 100644 index 0000000..4391309 --- /dev/null +++ b/string/FreeBSD/wmemcpy.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/FreeBSD/wmemmove.c b/string/FreeBSD/wmemmove.c new file mode 100644 index 0000000..dd2036c --- /dev/null +++ b/string/FreeBSD/wmemmove.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/FreeBSD/wmemset.c b/string/FreeBSD/wmemset.c new file mode 100644 index 0000000..df91537 --- /dev/null +++ b/string/FreeBSD/wmemset.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/string/Makefile.inc b/string/Makefile.inc index 0ac7762..c28c20e 100644 --- a/string/Makefile.inc +++ b/string/Makefile.inc @@ -1,17 +1,25 @@ # @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 -# $FreeBSD: src/lib/libc/string/Makefile.inc,v 1.25 2001/10/10 02:17:35 ache Exp $ +# $FreeBSD: src/lib/libc/string/Makefile.inc,v 1.32 2002/11/18 09:50:56 ru Exp $ .PATH: ${.CURDIR}/${MACHINE_ARCH}/string ${.CURDIR}/string CFLAGS+= -I${.CURDIR}/locale +.include "Makefile.fbsd_begin" # machine-independent string sources -MISRCS+=index.c rindex.c strcspn.c strpbrk.c strxfrm.c \ - memccpy.c rindix.c strdup.c strsep.c swab.c \ - memchr.c strcasecmp.c strerror.c strspn.c \ - memcmp.c strchr.c strftime.c strstr.c \ - memset.c strcoll.c strmode.c strtok.c \ - strlcat.c strlcpy.c +FBSDMISRCS+=bcmp.c bcopy.c bzero.c ffs.c index.c memccpy.c memchr.c memcmp.c \ + memcpy.c memmove.c memset.c rindex.c stpcpy.c strcasecmp.c strcat.c \ + strchr.c strcmp.c strcoll.c strcpy.c strcspn.c strdup.c strerror.c \ + strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c strncpy.c \ + strcasestr.c strnstr.c \ + strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \ + strxfrm.c swab.c wcscat.c wcschr.c wcscmp.c wcscoll.c wcscpy.c \ + wcscspn.c \ + wcslcat.c wcslcpy.c wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c \ + wcsrchr.c wcsspn.c wcsstr.c wcstok.c wcswidth.c wcsxfrm.c wmemchr.c \ + wmemcmp.c \ + wmemcpy.c wmemmove.c wmemset.c +.include "Makefile.fbsd_end" # machine-dependent string sources .if exists(${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc) @@ -19,17 +27,22 @@ MISRCS+=index.c rindex.c strcspn.c strpbrk.c strxfrm.c \ .endif .if ${LIB} == "c" -MAN3+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ +.include "Makefile.fbsd_begin" +FBSDMAN3= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 strerror.3 \ string.3 strlcpy.3 strlen.3 strmode.3 strpbrk.3 strrchr.3 strsep.3 \ - strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wmemchr.3 + strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wcscoll.3 wcstok.3 \ + wcswidth.3 wcsxfrm.3 wmemchr.3 +.include "Makefile.fbsd_end" MLINKS+=strcasecmp.3 strncasecmp.3 MLINKS+=strcat.3 strncat.3 MLINKS+=strcmp.3 strncmp.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 diff --git a/string/strcasecmp.c b/string/strcasecmp.c deleted file mode 100644 index 941dea6..0000000 --- a/string/strcasecmp.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -typedef unsigned char u_char; - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static const u_char charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', - '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', - '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', - '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', -}; - -int -strcasecmp(s1, s2) - const char *s1, *s2; -{ - register const u_char *cm = charmap, - *us1 = (const u_char *)s1, - *us2 = (const u_char *)s2; - - while (cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return (0); - return (cm[*us1] - cm[*--us2]); -} - -int -strncasecmp(s1, s2, n) - const char *s1, *s2; - register size_t n; -{ - if (n != 0) { - register const u_char *cm = charmap, - *us1 = (const u_char *)s1, - *us2 = (const u_char *)s2; - - do { - if (cm[*us1] != cm[*us2++]) - return (cm[*us1] - cm[*--us2]); - if (*us1++ == '\0') - break; - } while (--n != 0); - } - return (0); -} diff --git a/string/strcoll.c b/string/strcoll.c deleted file mode 100644 index 7be4315..0000000 --- a/string/strcoll.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 -#include - -/* - * Compare strings according to LC_COLLATE category of current locale. - */ -int -strcoll(s1, s2) - const char *s1, *s2; -{ - /* LC_COLLATE is unimplemented, hence always "C" */ - return (strcmp(s1, s2)); -} diff --git a/string/strerror.c b/string/strerror.c deleted file mode 100644 index 2bea97e..0000000 --- a/string/strerror.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (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 - -#define UPREFIX "Unknown error: " -static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ - -char * -strerror(num) - int num; -{ - extern const int sys_nerr; - extern const char *const sys_errlist[]; - register unsigned int errnum; - register char *p, *t; - char tmp[40]; - - errnum = num; /* convert to unsigned */ - if (errnum < sys_nerr) - return((char*)sys_errlist[errnum]); - - /* Do this by hand, so we don't include stdio(3). */ - t = tmp; - do { - *t++ = "0123456789"[errnum % 10]; - } while (errnum /= 10); - for (p = ebuf + sizeof(UPREFIX) - 1;;) { - *p++ = *--t; - if (t <= tmp) - break; - } - return(ebuf); -} diff --git a/string/strftime.c b/string/strftime.c deleted file mode 100644 index df63163..0000000 --- a/string/strftime.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include -#include -#include -#include - -static char *afmt[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", -}; -static char *Afmt[] = { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", - "Saturday", -}; -static char *bfmt[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", - "Oct", "Nov", "Dec", -}; -static char *Bfmt[] = { - "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December", -}; - -static size_t gsize; -static char *pt; -static int _add __P((char *)); -static int _conv __P((int, int, int)); -static int _secs __P((const struct tm *)); -static size_t _fmt __P((const char *, const struct tm *)); - -size_t -strftime(s, maxsize, format, t) - char *s; - size_t maxsize; - const char *format; - const struct tm *t; -{ - - pt = s; - if ((gsize = maxsize) < 1) - return(0); - if (_fmt(format, t)) { - *pt = '\0'; - return(maxsize - gsize); - } - return(0); -} - -static size_t -_fmt(format, t) - register const char *format; - const struct tm *t; -{ - for (; *format; ++format) { - if (*format == '%') - switch(*++format) { - case '\0': - --format; - break; - case 'A': - if (t->tm_wday < 0 || t->tm_wday > 6) - return(0); - if (!_add(Afmt[t->tm_wday])) - return(0); - continue; - case 'a': - if (t->tm_wday < 0 || t->tm_wday > 6) - return(0); - if (!_add(afmt[t->tm_wday])) - return(0); - continue; - case 'B': - if (t->tm_mon < 0 || t->tm_mon > 11) - return(0); - if (!_add(Bfmt[t->tm_mon])) - return(0); - continue; - case 'b': - case 'h': - if (t->tm_mon < 0 || t->tm_mon > 11) - return(0); - if (!_add(bfmt[t->tm_mon])) - return(0); - continue; - case 'C': - if (!_fmt("%a %b %e %H:%M:%S %Y", t)) - return(0); - continue; - case 'c': - if (!_fmt("%m/%d/%y %H:%M:%S", t)) - return(0); - continue; - case 'D': - if (!_fmt("%m/%d/%y", t)) - return(0); - continue; - case 'd': - if (!_conv(t->tm_mday, 2, '0')) - return(0); - continue; - case 'e': - if (!_conv(t->tm_mday, 2, ' ')) - return(0); - continue; - case 'H': - if (!_conv(t->tm_hour, 2, '0')) - return(0); - continue; - case 'I': - if (!_conv(t->tm_hour % 12 ? - t->tm_hour % 12 : 12, 2, '0')) - return(0); - continue; - case 'j': - if (!_conv(t->tm_yday + 1, 3, '0')) - return(0); - continue; - case 'k': - if (!_conv(t->tm_hour, 2, ' ')) - return(0); - continue; - case 'l': - if (!_conv(t->tm_hour % 12 ? - t->tm_hour % 12 : 12, 2, ' ')) - return(0); - continue; - case 'M': - if (!_conv(t->tm_min, 2, '0')) - return(0); - continue; - case 'm': - if (!_conv(t->tm_mon + 1, 2, '0')) - return(0); - continue; - case 'n': - if (!_add("\n")) - return(0); - continue; - case 'p': - if (!_add(t->tm_hour >= 12 ? "PM" : "AM")) - return(0); - continue; - case 'R': - if (!_fmt("%H:%M", t)) - return(0); - continue; - case 'r': - if (!_fmt("%I:%M:%S %p", t)) - return(0); - continue; - case 'S': - if (!_conv(t->tm_sec, 2, '0')) - return(0); - continue; - case 's': - if (!_secs(t)) - return(0); - continue; - case 'T': - case 'X': - if (!_fmt("%H:%M:%S", t)) - return(0); - continue; - case 't': - if (!_add("\t")) - return(0); - continue; - case 'U': - if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, - 2, '0')) - return(0); - continue; - case 'W': - if (!_conv((t->tm_yday + 7 - - (t->tm_wday ? (t->tm_wday - 1) : 6)) - / 7, 2, '0')) - return(0); - continue; - case 'w': - if (!_conv(t->tm_wday, 1, '0')) - return(0); - continue; - case 'x': - if (!_fmt("%m/%d/%y", t)) - return(0); - continue; - case 'y': - if (!_conv((t->tm_year + TM_YEAR_BASE) - % 100, 2, '0')) - return(0); - continue; - case 'Y': - if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0')) - return(0); - continue; - case 'Z': - if (!t->tm_zone || !_add(t->tm_zone)) - return(0); - 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) does. - */ - default: - break; - } - if (!gsize--) - return(0); - *pt++ = *format; - } - return(gsize); -} - -static int -_secs(t) - const struct tm *t; -{ - static char buf[15]; - register time_t s; - register char *p; - struct tm tmp; - - /* Make a copy, mktime(3) modifies the tm struct. */ - tmp = *t; - s = mktime(&tmp); - for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10) - *p-- = s % 10 + '0'; - return(_add(++p)); -} - -static int -_conv(n, digits, pad) - int n, digits, pad; -{ - static char buf[10]; - register char *p; - - for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) - *p-- = n % 10 + '0'; - while (p > buf && digits-- > 0) - *p-- = pad; - return(_add(++p)); -} - -static int -_add(str) - register char *str; -{ - for (;; ++pt, --gsize) { - if (!gsize) - return(0); - if (!(*pt = *str++)) - return(1); - } -} diff --git a/string/strxfrm.c b/string/strxfrm.c deleted file mode 100644 index 9a098fd..0000000 --- a/string/strxfrm.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, 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. - * - * 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 -#include - -/* - * Transform src, storing the result in dst, such that - * strcmp() on transformed strings returns what strcoll() - * on the original untransformed strings would return. - */ -size_t -strxfrm(dst, src, n) - register char *dst; - const char *src; - size_t n; -{ - register size_t srclen, copysize; - - /* - * Since locales are unimplemented, this is just a copy. - */ - srclen = strlen(src); - if (n != 0) { - copysize = srclen < n ? srclen : n - 1; - (void)memcpy(dst, src, copysize); - dst[copysize] = 0; - } - return (srclen); -} diff --git a/sys/Makefile.inc b/sys/Makefile.inc index bafd300..9172bca 100644 --- a/sys/Makefile.inc +++ b/sys/Makefile.inc @@ -18,9 +18,12 @@ .endif # Sources common to both syscall interfaces: -SRCS+= errno.c gettimeofday.c sigcatch.c sigsuspend.c getdtablesize.c \ - sigaction.c sigtramp.c crt_externs.c +# 3375657: patches for sem_open() sem_unlink() shm_open() shm_unlink() +CFLAGS+= -D__APPLE_PR3375657_HACK__ +SRCS+= errno.c gettimeofday.c sigcatch.c sigsuspend.c getdtablesize.c \ + sigaction.c sigtramp.c crt_externs.c \ + sem_open.c sem_unlink.c shm_open.c shm_unlink.c fix-3375657.c # Add machine dependent asm sources: SRCS+=${MDASM} diff --git a/sys/SYSCALL-LIST b/sys/SYSCALL-LIST index e49e492..f9234a1 100644 --- a/sys/SYSCALL-LIST +++ b/sys/SYSCALL-LIST @@ -22,6 +22,7 @@ dup2 execve _exit fcntl +fhopen flock fork fsync @@ -72,6 +73,7 @@ unmount mprotect msync munmap +nfsclnt nfssvc open pathconf diff --git a/sys/crt_externs.c b/sys/crt_externs.c index d86b8a6..ec6d7bb 100644 --- a/sys/crt_externs.c +++ b/sys/crt_externs.c @@ -32,17 +32,36 @@ #if defined(__DYNAMIC__) #include "mach-o/dyld.h" /* defines _dyld_lookup_and_bind() */ #define STRINGIFY(a) # a -#define DECLARE_VAR(var, type) \ +#define DECLARE_VAR(var, type) \ static type * var ## _pointer = 0 +#define DECLARE_PROGNAME(var, type) \ + static type * var ## _pointer = 0; \ + static type _priv_ ## var = 0 #define SETUP_VAR(var) \ if ( var ## _pointer == 0) { \ _dyld_lookup_and_bind( STRINGIFY(_ ## var), \ (unsigned long *) & var ## _pointer, 0); \ } +#define SETUP_PROGNAME(var) \ + if ( var ## _pointer == 0) { \ + if(NSIsSymbolNameDefined( STRINGIFY(_ ## var) )) \ + _dyld_lookup_and_bind( STRINGIFY(_ ## var), \ + (unsigned long *) & var ## _pointer, 0); \ + else { \ + char *progname = _dyld_get_image_name(0); \ + if(_priv_ ## var = strrchr(progname, '/')) \ + _priv_ ## var ++; \ + else \ + _priv_ ## var = progname; \ + var ## _pointer = & _priv_ ## var; \ + } \ + } #define USE_VAR(var) (var ## _pointer) #else #define DECLARE_VAR(var, type) extern type var +#define DECLARE_PROGNAME(var, type) DECLARE_VAR(var, type) #define SETUP_VAR(var) +#define SETUP_PROGNAME(var) SETUP_VAR(var) #define USE_VAR(var) (& var) #endif @@ -65,8 +84,8 @@ char ***_NSGetEnviron(void) { } char **_NSGetProgname(void) { - DECLARE_VAR(__progname, char *); - SETUP_VAR(__progname); + DECLARE_PROGNAME(__progname, char *); + SETUP_PROGNAME(__progname); return(USE_VAR(__progname)); } @@ -105,5 +124,3 @@ void *__eh_value_gcc_272 = (void *)0; /* This is what egcs uses for its global data pointer */ void *__eh_global_dataptr = (void *)0; - -void *__keymgr_global[3] = { (void *)0 }; diff --git a/sys/errno.c b/sys/errno.c index e2a4e5e..bbede63 100644 --- a/sys/errno.c +++ b/sys/errno.c @@ -35,7 +35,7 @@ extern int errno; int *__error(void) { pthread_t self = pthread_self(); /* If we're not a detached pthread, just return the global errno */ - if ((self == (pthread_t)0) || (self->sig != _PTHREAD_SIG) || (self->detached & _PTHREAD_CREATE_PARENT)) { + if ((self == (pthread_t)0) || (self->sig != _PTHREAD_SIG)) { return &errno; } return &self->err_no; diff --git a/sys/fix-3375657.c b/sys/fix-3375657.c new file mode 100644 index 0000000..e60c9bb --- /dev/null +++ b/sys/fix-3375657.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifdef __APPLE_PR3375657_HACK__ + +/* + * When mutexes or spinlocks were added for thread safety, the system would + * hang during the boot process, just after changing to the blue background. + * So for the common case of not calling _s[eh]m_hack_{add,init}(), we just + * use static name lists. This should be reinvestigated when there is time. + */ + +#define PRIVATE __private_extern__ +//#define SEM_DEBUG_FILE "/tmp/sem_names" +//#define SHM_DEBUG_FILE "/tmp/shm_names" + +#if defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) +#include +#include +#endif /* defined(SEM_DEBUG_FILE) || defined(SHM_DEBUG_FILE) */ +#include +#include +#include + +#ifdef SEM_DEBUG_FILE +#define SEM_PRINTF(fmt, args...) \ +{ \ + FILE *_sem_fp_; \ + if (access(SEM_DEBUG_FILE, F_OK) == 0 && \ + (_sem_fp_ = fopen(SEM_DEBUG_FILE, "a")) != NULL) { \ + fprintf(_sem_fp_, fmt, ## args); \ + fclose(_sem_fp_); \ + } \ +} +#endif /* SEM_DEBUG_FILE */ +#ifdef SHM_DEBUG_FILE +#define SHM_PRINTF(fmt, args...) \ +{ \ + FILE *_shm_fp_; \ + if (access(SHM_DEBUG_FILE, F_OK) == 0 && \ + (_shm_fp_ = fopen(SHM_DEBUG_FILE, "a")) != NULL) { \ + fprintf(_shm_fp_, fmt, ## args); \ + fclose(_shm_fp_); \ + } \ +} +#endif /* SHM_DEBUG_FILE */ + +/*----------------------------------------------------------------------- + * For the Hack structure: + * + * first >= 0 starting serial number + * first < 0 no serial number + * last ending serial number (only if first >= 0) + * debug whether an option 'D' can be appended + *-----------------------------------------------------------------------*/ +typedef struct { + const char *name; + int first; + int last; + int debug; +} Hack; + +/*----------------------------------------------------------------------- + * For the HackList structure: + * + * list the list of Hack structures + * cur the number of valid Hack structures in list + * max the actual number of Hack structures allocated + *-----------------------------------------------------------------------*/ +#define HACKLISTDELTA 16 +#define HACKLISTSTART 16 +typedef struct { + const Hack *list; + int cur; + int max; +} HackList; + +static const Hack sem_hack_default_names[] = { + {"EDBPool", 1, 255, 0}, + {"EDDPoolLock", -1, 0, 0}, + {"Mso97SharedDg", 1920, 2047, 1}, + {"Office", 1920, 2047, 1}, + {"PT_EDBPool", 1, 255, 0}, + {"PT_EDDPoolLock", -1, 0, 0}, + {"PT_Mso97SharedDg", 1920, 2047, 0}, + {"PT_Office", 1920, 2047, 0}, + {"ShMemExtCritSection", -1, 0, 0}, + {"ShMemIntCritSection", -1, 0, 0}, + {NULL, 0, 0, 0}, +}; +static HackList sem_hack_defaults = { + sem_hack_default_names, + (sizeof(sem_hack_default_names) / sizeof(const Hack)) - 1, + 0 +}; +static HackList *sem_hack_names = &sem_hack_defaults; + +static const Hack shm_hack_default_names[] = { + {"EDBPool", 1, 255, 0}, + {"EDDPoolLock", -1, 0, 0}, + {"Mso97SharedDg", 1920, 2047, 1}, + {"Office", 1920, 2047, 1}, + {"PT_EDBPool", 1, 255, 0}, + {"PT_EDDPoolLock", -1, 0, 0}, + {"PT_Mso97SharedDg", 1920, 2047, 0}, + {"PT_Office", 1920, 2047, 0}, + {"PT_ShMemRefCount", -1, 0, 0}, /* not specified by MS, but seen */ + {"ShMemRefCount", -1, 0, 0}, + {NULL, 0, 0, 0}, +}; +static HackList shm_hack_defaults = { + shm_hack_default_names, + (sizeof(shm_hack_default_names) / sizeof(const Hack)) - 1, + 0 +}; +static HackList *shm_hack_names = &shm_hack_defaults; + +static int comparkey(const void *key, const void *hname); +static int comparstr(const void *a, const void *b); +static int dosearch(const char *name, const HackList *hl); +static int hl_add(HackList *hl, const Hack *h); +static void hl_free(HackList *hl); +static HackList *hl_init(void); +static HackList *initList(const Hack *list); +int _sem_hack_add(const Hack *list); +void _sem_hack_init(void); +PRIVATE int _sem_match(const char *name); +int _shm_hack_add(const Hack *list); +void _shm_hack_init(void); +PRIVATE int _shm_match(const char *name); + +/*----------------------------------------------------------------------- + * comparkey - used by bsearch to find the Hack structure with the given key + *-----------------------------------------------------------------------*/ +static int +comparkey(const void *key, const void *h) +{ + return strcmp(key, ((const Hack *)h)->name); +} + +/*----------------------------------------------------------------------- + * comparstr - used by qsort to sort the Hack list + *-----------------------------------------------------------------------*/ +static int +comparstr(const void *a, const void *b) +{ + return strcmp(((const Hack *)a)->name, ((const Hack *)b)->name); +} + +/*----------------------------------------------------------------------- + * dosearch - search of the given name in the given HackList. First see + * if there is a trailing D, and a serial number. If the serial number + * exists, try to match without the serial number, checking the series + * range and whether the trailing D is allowed. Otherwise, try to match + * the whole string, but check if the matched Hack structure requires a + * serial number. + *-----------------------------------------------------------------------*/ +static int +dosearch(const char *name, const HackList *hl) +{ + int series; + int len = strlen(name); + const char *end, *p; + char *key; + const Hack *h; + + end = name + len - 1; + if (*end != 'D') + end++; + p = end - 1; + while (p >= name && *p >= '0' && *p <= '9') + p--; + p++; + if (p < end && (len = p - name) > 0) { + key = alloca(len + 1); + if (key) { + series = atoi(p); + strncpy(key, name, len); + key[len] = 0; + h = (const Hack *)bsearch(key, hl->list, hl->cur, + sizeof(const Hack), comparkey); + if (h && h->first >= 0 + && series >= h->first && series <= h->last + && (*end == 0 || h->debug)) + return 1; + } + } + h = (const Hack *)bsearch(name, hl->list, hl->cur, sizeof(const Hack), + comparkey); + return (h && h->first < 0); +} + +/*----------------------------------------------------------------------- + * hl_add - append to the given HackList a copy of the given Hack structure + *-----------------------------------------------------------------------*/ +static int +hl_add(HackList *hl, const Hack *c) +{ + int i = hl->cur; + Hack *h; + + if (!c->name) + return -1; + if (i >= hl->max) { + int s = hl->max + HACKLISTDELTA; + const Hack *new = (const Hack *)realloc((void *)hl->list, + s * sizeof(const Hack)); + + if (!new) + return -1; + hl->list = new; + hl->max = s; + } + h = (Hack *)(hl->list + i); + if ((h->name = strdup(c->name)) == NULL) + return -1; + h->first = c->first; + h->last = c->last; + h->debug = c->debug; + hl->cur++; + return 0; +} + +/*----------------------------------------------------------------------- + * hl_free - deallocate all memory from the given HackList + *-----------------------------------------------------------------------*/ +static void +hl_free(HackList *hl) +{ + const Hack *h; + int i; + + for (h = hl->list, i = hl->cur; i > 0; h++, i--) + free((void *)h->name); + free((void *)hl->list); + free(hl); +} + +/*----------------------------------------------------------------------- + * hl_init - create a new HackList, with preallocated Hack structures + *-----------------------------------------------------------------------*/ +static HackList * +hl_init(void) +{ + HackList *hl = (HackList *)malloc(sizeof(HackList)); + + if (!hl) + return NULL; + hl->list = (Hack *)malloc(HACKLISTSTART * sizeof(Hack)); + if (!hl->list) { + free(hl); + return NULL; + } + hl->cur = 0; + hl->max = HACKLISTSTART; + return hl; +} + +/*----------------------------------------------------------------------- + * initList - initialize a new HackList with the given list of Hack structures + *-----------------------------------------------------------------------*/ +static HackList * +initList(const Hack *list) +{ + HackList *hl = hl_init(); + + if (hl == NULL) + return NULL; + for (; list->name; list++) + if (hl_add(hl, list) < 0) { + hl_free(hl); + return NULL; + } + return hl; +} + +/*----------------------------------------------------------------------- + * PUBLIC _sem_hack_add - add the given Hack list to sem_hack_names. + *-----------------------------------------------------------------------*/ +int +_sem_hack_add(const Hack *list) +{ + if (list == NULL) + return -1; + if (sem_hack_names == &sem_hack_defaults) { + HackList *hl = initList(sem_hack_default_names); + if (!hl) + return -1; + sem_hack_names = hl; + } + for (; list->name; list++) + if (hl_add(sem_hack_names, list) < 0) + return -1; + qsort((void *)sem_hack_names->list, sem_hack_names->cur, + sizeof(const Hack), comparstr); + return 0; +} + +/*----------------------------------------------------------------------- + * PUBLIC _sem_hack_init - reinitialize sem_hack_names to the default + *-----------------------------------------------------------------------*/ +void +_sem_hack_init(void) +{ + if (sem_hack_names == &sem_hack_defaults) + return; + hl_free(sem_hack_names); + sem_hack_names = &sem_hack_defaults; +} + +/*----------------------------------------------------------------------- + * _sem_match - try to match the given named to sem_hack_names. Called + * by sem_open() and sem_unlink(). + *-----------------------------------------------------------------------*/ +PRIVATE int +_sem_match(const char *name) +{ +#ifdef SEM_DEBUG_FILE + int match; +#endif /* SEM_DEBUG_FILE */ + + if (!name || !*name) + return 0; +#ifdef SEM_DEBUG_FILE + match = dosearch(name, sem_hack_names); + if (!match) + SEM_PRINTF("%s\n", name); + return match; +#else /* SEM_DEBUG_FILE */ + return dosearch(name, sem_hack_names); +#endif /* SEM_DEBUG_FILE */ +} + +/*----------------------------------------------------------------------- + * PUBLIC _shm_hack_add - add the given Hack list to shm_hack_names. + *-----------------------------------------------------------------------*/ +int +_shm_hack_add(const Hack *list) +{ + if (list == NULL) + return -1; + if (shm_hack_names == &shm_hack_defaults) { + HackList *hl = initList(shm_hack_default_names); + if (!hl) + return -1; + shm_hack_names = hl; + } + for (; list->name; list++) + if (hl_add(shm_hack_names, list) < 0) + return -1; + qsort((void *)shm_hack_names->list, shm_hack_names->cur, + sizeof(const Hack), comparstr); + return 0; +} + +/*----------------------------------------------------------------------- + * PUBLIC _shm_hack_init - reinitialize shm_hack_names to the default + *-----------------------------------------------------------------------*/ +void +_shm_hack_init(void) +{ + if (shm_hack_names == &shm_hack_defaults) + return; + hl_free(shm_hack_names); + shm_hack_names = &shm_hack_defaults; +} + +/*----------------------------------------------------------------------- + * _shm_match - try to match the given named to shm_hack_names. Called + * by shm_open() and shm_unlink(). + *-----------------------------------------------------------------------*/ +PRIVATE int +_shm_match(const char *name) +{ +#ifdef SHM_DEBUG_FILE + int match; +#endif /* SHM_DEBUG_FILE */ + + if (!name || !*name) + return 0; +#ifdef SHM_DEBUG_FILE + match = dosearch(name, shm_hack_names); + if (!match) + SHM_PRINTF("%s\n", name); + return match; +#else /* SHM_DEBUG_FILE */ + return dosearch(name, shm_hack_names); +#endif /* SHM_DEBUG_FILE */ +} + +#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/getdtablesize.c b/sys/getdtablesize.c index c25bf90..b6673e2 100644 --- a/sys/getdtablesize.c +++ b/sys/getdtablesize.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ #include int getdtablesize() { diff --git a/sys/gettimeofday.c b/sys/gettimeofday.c index 1a0e4bb..728b659 100644 --- a/sys/gettimeofday.c +++ b/sys/gettimeofday.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -35,38 +35,50 @@ #include #include +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + + int gettimeofday (struct timeval *tp, struct timezone *tzp) { static int validtz = 0; static struct timezone cached_tz = {0}; struct timeval localtv; -#ifdef __ppc__ - extern __ppc_gettimeofday(struct timeval *, struct timezone *); -#endif - if (tzp && (tp == NULL) && (validtz == 0)) { - tp = &localtv; + if (tp == NULL) { + if (tzp == NULL) + return (0); + tp = &localtv; } #ifdef __ppc__ - if(__ppc_gettimeofday(tp, tzp)) - return(-1); + { + extern int __ppc_gettimeofday(struct timeval *, struct timezone *); + extern int __commpage_gettimeofday(struct timeval *); + + if (__commpage_gettimeofday(tp)) { /* first try commpage */ + if (__ppc_gettimeofday(tp,tzp)) { /* if it fails, use syscall */ + return (-1); + } + } + } #else if (syscall (SYS_gettimeofday, tp, tzp) < 0) { return (-1); } #endif 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; + 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/sem_open.c b/sys/sem_open.c new file mode 100644 index 0000000..e60ee61 --- /dev/null +++ b/sys/sem_open.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifdef __APPLE_PR3375657_HACK__ + +#include +#include +#include +#include +#include +#include +#include +#include + +__private_extern__ int _sem_match(const char *name); + +sem_t * +sem_open (const char *name, int flags, ...) +{ + char *buffer; + va_list ap; + int mode; + unsigned int value; + + /* + * To work-around applications that don't play + * well in multiple GUI sessions, we append + * shared memory names with the effective user ID. + * It would be better to append the region name + * with a session ID, but nothing like that + * exists at this level of the system yet. + */ + + if (_sem_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { + sprintf(buffer, "%s\t%d", name, geteuid()); + name = buffer; + } + +// sem_open (const char *name, int flags, mode_t mode, unsigned int value) + va_start(ap, flags); + mode = va_arg(ap, int); /* promoted from mode_t to int */ + value = va_arg(ap, unsigned int); + va_end(ap); + + return syscall (SYS_sem_open, name, flags, mode, value); +} + +#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/gen/sleep.c b/sys/sem_unlink.c similarity index 55% rename from gen/sleep.c rename to sys/sem_unlink.c index 0175147..10e0dd9 100644 --- a/gen/sleep.c +++ b/sys/sem_unlink.c @@ -23,27 +23,37 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#ifdef __APPLE_PR3375657_HACK__ -extern int nanosleep(const struct timespec *, struct timespec *); +#include +#include +#include +#include +#include +#include -/* We use nanosleep and let it set errno, and compute the residual for us. */ -unsigned int -sleep(unsigned int seconds) +__private_extern__ int _sem_match(const char *name); + +int +sem_unlink (const char *name) { - struct timespec req, rem; - - if (seconds == 0) { - return 0; - } - req.tv_sec = seconds; - req.tv_nsec = 0; - - /* It's not clear from the spec whether the remainder will be 0 - ** if we weren't interrupted - */ - if (nanosleep(&req, &rem) == -1) { - return (unsigned int)rem.tv_sec; - } - return 0; + char *buffer; + + /* + * To work-around applications that don't play + * well in multiple GUI sessions, we append + * shared memory names with the effective user ID. + * It would be better to append the region name + * with a session ID, but nothing like that + * exists at this level of the system yet. + */ + + if (_sem_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { + sprintf(buffer, "%s\t%d", name, geteuid()); + name = buffer; + } + + return syscall (SYS_sem_unlink, name); } + +#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/shm_open.c b/sys/shm_open.c new file mode 100644 index 0000000..3ec0411 --- /dev/null +++ b/sys/shm_open.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifdef __APPLE_PR3375657_HACK__ + +#include +#include +#include +#include +#include +#include + +__private_extern__ int _shm_match(const char *name); + +int +shm_open (const char *name, int flags, mode_t mode) +{ + char *buffer; + + /* + * To work-around applications that don't play + * well in multiple GUI sessions, we append + * shared memory names with the effective user ID. + * It would be better to append the region name + * with a session ID, but nothing like that + * exists at this level of the system yet. + */ + + if (_shm_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { + sprintf(buffer, "%s\t%d", name, geteuid()); + name = buffer; + } + + return syscall (SYS_shm_open, name, flags, mode); +} + +#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/i386/threads/thread.c b/sys/shm_unlink.c similarity index 54% rename from i386/threads/thread.c rename to sys/shm_unlink.c index 142d3a1..07e1ad6 100644 --- a/i386/threads/thread.c +++ b/sys/shm_unlink.c @@ -22,38 +22,38 @@ * * @APPLE_LICENSE_HEADER_END@ */ -/* - * Mach Operating System - * Copyright (c) 1989 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ -/* - * 386/thread.c - * - * Cproc startup for 386 MTHREAD implementation. - */ +#ifdef __APPLE_PR3375657_HACK__ -#include -#include -#include -#include "cthread_internals.h" +#include +#include +#include +#include +#include +#include -void -_pthread_set_self(p) - cproc_t p; -{ - asm("pushl %0" : : "m" (p)); - asm("pushl $0"); // fake the kernel out - asm("movl $1, %%eax" : : : "ax"); - asm("lcall $0x3b, $0"); - asm("addl $0x8, %%esp" ::); -} +__private_extern__ int _shm_match(const char *name); -void * -pthread_self() +int +shm_unlink (const char *name) { - asm("movl $0, %eax"); - asm("lcall $0x3b, $0"); + char *buffer; + + /* + * To work-around applications that don't play + * well in multiple GUI sessions, we append + * shared memory names with the effective user ID. + * It would be better to append the region name + * with a session ID, but nothing like that + * exists at this level of the system yet. + */ + + if (_shm_match(name) && (buffer = alloca(strlen(name) + 32)) != NULL) { + sprintf(buffer, "%s\t%d", name, geteuid()); + name = buffer; + } + + return syscall (SYS_shm_unlink, name); } + +#endif /* __APPLE_PR3375657_HACK__ */ diff --git a/sys/sigaction.c b/sys/sigaction.c index 2737a91..9b57cc4 100644 --- a/sys/sigaction.c +++ b/sys/sigaction.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -49,8 +50,6 @@ sigaction__ (sig, nsv, osv, bind) register struct sigaction *nsv, *osv; int bind; { - struct sigaction vec; - void (*prevsig)(); extern void _sigtramp(); struct __sigaction sa; struct __sigaction *sap; diff --git a/sys/sigtramp.c b/sys/sigtramp.c index cb1ad53..373d1ff 100644 --- a/sys/sigtramp.c +++ b/sys/sigtramp.c @@ -41,6 +41,117 @@ int __in_sigtramp = 0; #endif +/* These defn should match the kernel one */ +#define UC_TRAD 1 +#ifdef __ppc__ +#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 + + /* The following are valid mcontext sizes */ +#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int)) + +#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) + +#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int)) + +#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) +#endif + +#ifdef __ppc__ +/* This routine will be replaced by an assembly soon */ +static int +restore64_state(mcontext_t mctx, mcontext64_t mctx64) +{ + if (mctx->ss.srr0 != (unsigned int)mctx64->ss.srr0) + return(0); + if (mctx->ss.srr1 != (unsigned int)mctx64->ss.srr1) + return(0); + if (mctx->ss.r0 != (unsigned int)mctx64->ss.r0) + return(0); + if (mctx->ss.r1 != (unsigned int)mctx->ss.r1) + return(0); + if (mctx->ss.r2 != (unsigned int)mctx->ss.r2) + return(0); + if (mctx->ss.r3 != (unsigned int)mctx->ss.r3) + return(0); + if (mctx->ss.r4 != (unsigned int)mctx->ss.r4) + return(0); + if (mctx->ss.r5 != (unsigned int)mctx->ss.r5) + return(0); + if (mctx->ss.r6 != (unsigned int)mctx->ss.r6) + return(0); + if (mctx->ss.r7 != (unsigned int)mctx->ss.r7) + return(0); + if (mctx->ss.r8 != (unsigned int)mctx->ss.r8) + return(0); + if (mctx->ss.r9 != (unsigned int)mctx->ss.r9) + return(0); + if (mctx->ss.r10 != (unsigned int)mctx->ss.r10) + return(0); + if (mctx->ss.r11 != (unsigned int)mctx->ss.r11) + return(0); + if (mctx->ss.r12 != (unsigned int)mctx->ss.r12) + return(0); + if (mctx->ss.r13 != (unsigned int)mctx->ss.r13) + return(0); + if (mctx->ss.r14 != (unsigned int)mctx->ss.r14) + return(0); + if (mctx->ss.r15 != (unsigned int)mctx->ss.r15) + return(0); + if (mctx->ss.r16 != (unsigned int)mctx->ss.r16) + return(0); + if (mctx->ss.r17 != (unsigned int)mctx->ss.r17) + return(0); + if (mctx->ss.r18 != (unsigned int)mctx->ss.r18) + return(0); + if (mctx->ss.r19 != (unsigned int)mctx->ss.r19) + return(0); + if (mctx->ss.r20 != (unsigned int)mctx->ss.r20) + return(0); + if (mctx->ss.r21 != (unsigned int)mctx->ss.r21) + return(0); + if (mctx->ss.r22 != (unsigned int)mctx64->ss.r22) + return(0); + if (mctx->ss.r23 != (unsigned int)mctx64->ss.r23) + return(0); + if (mctx->ss.r24 != (unsigned int)mctx64->ss.r24) + return(0); + if (mctx->ss.r25 != (unsigned int)mctx64->ss.r25) + return(0); + if (mctx->ss.r26 != (unsigned int)mctx64->ss.r26) + return(0); + if (mctx->ss.r27 != (unsigned int)mctx64->ss.r27) + return(0); + if (mctx->ss.r28 != (unsigned int)mctx64->ss.r28) + return(0); + if (mctx->ss.r29 != (unsigned int)mctx64->ss.r29) + return(0); + if (mctx->ss.r30 != (unsigned int)mctx64->ss.r30) + return(0); + if (mctx->ss.r31 != (unsigned int)mctx64->ss.r31) + return(0); + + if (mctx->ss.cr != mctx64->ss.cr) + return(0); + if (mctx->ss.xer != (unsigned int)mctx64->ss.xer) + return(0); + if (mctx->ss.lr != (unsigned int)mctx64->ss.lr) + return(0); + if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr) + return(0); + + return(1); + +} + +#endif + void _sigtramp( union __sigaction_u __sigaction_u, @@ -49,19 +160,59 @@ _sigtramp( siginfo_t *sinfo, struct ucontext *uctx ) { +#ifdef __ppc__ + int ctxstyle = UC_FLAVOR; +#endif + mcontext_t mctx; + mcontext64_t mctx64; #if defined(__DYNAMIC__) __in_sigtramp++; #endif - if (sigstyle == 1) +#ifndef __ppc__ + if (sigstyle == UC_TRAD) sa_handler(sig); -#ifdef __ppc__ +#else /* __ppc__ */ + if ((sigstyle == UC_TRAD) || (sigstyle == UC_TRAD64) || (sigstyle == UC_TRAD64_VEC)) + sa_handler(sig); + else sa_sigaction(sig, sinfo, uctx); -#endif /* __ppc__ */ + if ((sigstyle == UC_DUAL) || (sigstyle == UC_DUAL_VEC)) { + mctx = uctx->uc_mcontext; + mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext)); + /* restore 64bit state ? */ + if (restore64_state(mctx, mctx64)) { + uctx->uc_mcontext = (void *)mctx64; + if (sigstyle == UC_DUAL) { + uctx->uc_mcsize = UC_FLAVOR64_SIZE; + ctxstyle = UC_FLAVOR64; + } else { + uctx->uc_mcsize = UC_FLAVOR64_VEC_SIZE; + ctxstyle = UC_FLAVOR64_VEC; + } + } else { + if (sigstyle == UC_DUAL) + ctxstyle = UC_FLAVOR; + else + ctxstyle = UC_FLAVOR_VEC; + } + } else + ctxstyle = sigstyle; +#endif /* __ppc__ */ + #if defined(__DYNAMIC__) __in_sigtramp--; #endif - sigreturn(uctx); +#ifdef __ppc__ + { + /* sigreturn(uctx, ctxstyle); */ + /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ + syscall (184, uctx, ctxstyle); + } +#else + sigreturn(uctx); +#endif /* __ppc__ */ } + diff --git a/sys/sigwait.2 b/sys/sigwait.2 index 5309a79..e72d736 100644 --- a/sys/sigwait.2 +++ b/sys/sigwait.2 @@ -53,8 +53,14 @@ to the signal number that was cleared. .Pp The signals specified by .Fa set -should be blocked at the time of the call to +should be blocked, but not ignored, at the time of the call to .Fn sigwait . +.Pp +Processes which call +.Fn sigwait +on ignored signals will wait indefinately. Ignored +signals are dropped immeadiately by the system, before delivery +to a waiting process. .Sh RETURN VALUES If successful, .Fn sigwait @@ -79,4 +85,3 @@ specifies one or more invalid signal numbers. .Sh STANDARDS .Fn sigwait conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') - diff --git a/threads/cprocs.c b/threads/cprocs.c index 72b6f5b..8458699 100644 --- a/threads/cprocs.c +++ b/threads/cprocs.c @@ -64,8 +64,6 @@ extern void alloc_stack(), _dealloc_stack(); extern mach_port_t mach_thread_self(); extern boolean_t swtch_pri(); -private int cprocs_started = FALSE; - #ifdef CTHREADS_DEBUG private void print_cproc(p) @@ -100,12 +98,11 @@ print_cproc_queue(name, queue) cthread_queue_map(queue, cproc_t, print_cproc); printf("\n"); } -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ -private int cproc_lock = 0; /* unlocked */ +#ifdef CTHREADS_DEBUG private cproc_t cprocs = NO_CPROC; /* linked list of cprocs */ -#ifdef CTHREADS_DEBUG private void print_all_cprocs() { @@ -116,7 +113,7 @@ print_all_cprocs() print_cproc(p); printf("\n"); } -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ /* * Routines for supporting fork() of multi-threaded programs. diff --git a/threads/cthreads.c b/threads/cthreads.c index 26d4a66..6fd75b5 100644 --- a/threads/cthreads.c +++ b/threads/cthreads.c @@ -64,7 +64,7 @@ extern void _longjmp(jmp_buf env, int val); #ifdef CTHREADS_DEBUG int cthread_debug = FALSE; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ /* * Routines for supporting fork() of multi-threaded programs. @@ -73,9 +73,11 @@ int cthread_debug = FALSE; extern void _malloc_fork_prepare(), _malloc_fork_parent(); extern void _malloc_fork_child(); +extern void fork_mach_init(); extern void _cproc_fork_child(), _stack_fork_child(); extern void _lu_fork_child(void); -extern void _pthread_fork_child(void); +extern void _pthread_fork_child(pthread_t); +extern void _notify_fork_child(void); static pthread_t psaved_self = 0; static pthread_lock_t psaved_self_global_lock = LOCK_INITIALIZER; @@ -111,8 +113,6 @@ void _cthread_fork_child() * Called in the child process after a fork syscall. Releases locks acquired * by cthread_fork_prepare(). Deallocates cthread data structures which * described other threads in our parent. Makes this thread the main thread. - * - * The mach_init() routine must be called in the child before this routine. */ { pthread_t p = psaved_self; @@ -122,7 +122,7 @@ void _cthread_fork_child() mig_fork_child(); _malloc_fork_child(); p->kernel_thread = mach_thread_self(); - p->reply_port = MACH_PORT_NULL; + p->reply_port = mach_reply_port(); p->mutexes = NULL; p->cleanup_stack = NULL; p->death = MACH_PORT_NULL; @@ -130,11 +130,14 @@ void _cthread_fork_child() p->detached |= _PTHREAD_CREATE_PARENT; _spin_unlock(&p->lock); - _cproc_fork_child(); + fork_mach_init(); + _pthread_fork_child(p); + + _cproc_fork_child(); _lu_fork_child(); - _pthread_fork_child(); + _notify_fork_child(); __is_threaded = 0; diff --git a/threads/lu_utils.c b/threads/lu_utils.c index 090f2e9..fce485a 100644 --- a/threads/lu_utils.c +++ b/threads/lu_utils.c @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ /* * Port and memory management for doing lookups to the lookup server * Copyright (C) 1989 by NeXT, Inc. @@ -9,7 +33,11 @@ * */ #include +#include +#include +#include #include +#include #include mach_port_t _lu_port = MACH_PORT_NULL; diff --git a/threads/mig_support.c b/threads/mig_support.c index 4c5856b..c744bc4 100644 --- a/threads/mig_support.c +++ b/threads/mig_support.c @@ -83,11 +83,11 @@ mig_get_reply_port() pthread_t pself; #ifdef CTHREADS_DEBUG int d = cthread_debug; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ #ifdef CTHREADS_DEBUG cthread_debug = FALSE; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ pself = pthread_self(); if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { if (pself->reply_port == MACH_PORT_NULL) { @@ -99,7 +99,7 @@ mig_get_reply_port() if (self == NO_CPROC) { #ifdef CTHREADS_DEBUG cthread_debug = d; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ return(_task_reply_port); } if (self->reply_port == MACH_PORT_NULL) { @@ -107,7 +107,7 @@ mig_get_reply_port() } #ifdef CTHREADS_DEBUG cthread_debug = d; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ return self->reply_port; } @@ -124,11 +124,11 @@ mig_dealloc_reply_port(mach_port_t migport) register mach_port_t port; #ifdef CTHREADS_DEBUG int d = cthread_debug; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ #ifdef CTHREADS_DEBUG cthread_debug = FALSE; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ pself = pthread_self(); if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { port = pself->reply_port; @@ -145,7 +145,7 @@ mig_dealloc_reply_port(mach_port_t migport) if (self == NO_CPROC) { #ifdef CTHREADS_DEBUG cthread_debug = d; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ return; } ASSERT(self != NO_CPROC); @@ -159,7 +159,7 @@ mig_dealloc_reply_port(mach_port_t migport) } #ifdef CTHREADS_DEBUG cthread_debug = d; -#endif CTHREADS_DEBUG +#endif /* CTHREADS_DEBUG */ } /************************************************************* diff --git a/util/Makefile.inc b/util/Makefile.inc index 8151c6b..a8d0c80 100644 --- a/util/Makefile.inc +++ b/util/Makefile.inc @@ -1,3 +1,8 @@ .PATH: ${.CURDIR}/${MACHINE_ARCH}/util ${.CURDIR}/util -SRCS += login.c login_tty.c logout.c logwtmp.c pty.c +SRCS += login.c login_tty.c logout.c logwtmp.c pty.c fparseln.c \ + opendev.c + +.if ${LIB} == "c" +MAN3 += fparseln.3 opendev.3 +.endif diff --git a/util/fparseln.3 b/util/fparseln.3 new file mode 100644 index 0000000..afb4688 --- /dev/null +++ b/util/fparseln.3 @@ -0,0 +1,156 @@ +.\" $NetBSD: fparseln.3,v 1.7 1999/07/02 15:49:12 simonb Exp $ +.\" $FreeBSD: src/lib/libutil/fparseln.3,v 1.9 2001/10/01 16:09:18 ru Exp $ +.\" +.\" Copyright (c) 1997 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. +.\" +.Dd December 1, 1997 +.Dt FPARSELN 3 +.Os +.Sh NAME +.Nm fparseln +.Nd return the next logical line from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In util.h +.Ft "char *" +.Fo fparseln +.Fa "FILE *stream" "size_t *len" "size_t *lineno" +.Fa "const char delim[3]" "int flags" +.Fc +.Sh DESCRIPTION +The +.Fn fparseln +function +returns a pointer to the next logical line from the stream referenced by +.Fa stream . +This string is +.Dv NUL +terminated and it is dynamically allocated on each invocation. +It is the +responsibility of the caller to free the pointer. +.Pp +By default, if a character is escaped, both it and the preceding escape +character will be present in the returned string. +Various +.Fa flags +alter this behaviour. +.Pp +The meaning of the arguments is as follows: +.Bl -tag -width "lineno" +.It Fa stream +The stream to read from. +.It Fa len +If not +.Dv NULL , +the length of the string is stored in the memory location to which it +points. +.It Fa lineno +If not +.Dv NULL , +the value of the memory location to which is pointed to, is incremented +by the number of lines actually read from the file. +.It Fa delim +Contains the escape, continuation, and comment characters. +If a character is +.Dv NUL +then processing for that character is disabled. +If +.Dv NULL , +all characters default to values specified below. +The contents of +.Fa delim +is as follows: +.Bl -tag -width "delim[0]" +.It Fa delim[0] +The escape character, which defaults to +.Cm \e , +is used to remove any special meaning from the next character. +.It Fa delim[1] +The continuation character, which defaults to +.Cm \e , +is used to indicate that the next line should be concatenated with the +current one if this character is the last character on the current line +and is not escaped. +.It Fa delim[2] +The comment character, which defaults to +.Cm # , +if not escaped indicates the beginning of a comment that extends until the +end of the current line. +.El +.It Fa flags +If non-zero, alter the operation of +.Fn fparseln . +The various flags, which may be +.Em or Ns -ed +together, are: +.Bl -tag -width "FPARSELN_UNESCCOMM" +.It Dv FPARSELN_UNESCCOMM +Remove escape preceding an escaped comment. +.It Dv FPARSELN_UNESCCONT +Remove escape preceding an escaped continuation. +.It Dv FPARSELN_UNESCESC +Remove escape preceding an escaped escape. +.It Dv FPARSELN_UNESCREST +Remove escape preceding any other character. +.It Dv FPARSELN_UNESCALL +All of the above. +.El +.Pp +.El +.Sh RETURN VALUES +Upon successful completion a pointer to the parsed line is returned; +otherwise, +.Dv NULL +is returned. +.Pp +The +.Fn fparseln +function uses internally +.Xr fgetln 3 , +so all error conditions that apply to +.Xr fgetln 3 , +apply to +.Fn fparseln . +In addition +.Fn fparseln +may set +.Va errno +to +.Er ENOMEM +and return +.Dv NULL +if it runs out of memory. +.Sh SEE ALSO +.Xr fgetln 3 +.Sh HISTORY +The +.Fn fparseln +function first appeared in +.Nx 1.4 . diff --git a/util/fparseln.c b/util/fparseln.c new file mode 100644 index 0000000..a740dd1 --- /dev/null +++ b/util/fparseln.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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 $ */ + +/* + * Copyright (c) 1997 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. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libutil/fparseln.c,v 1.5 2002/03/21 23:52:49 obrien Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +static int isescaped(const char *, const char *, int); + +/* isescaped(): + * Return true if the character in *p that belongs to a string + * that starts in *sp, is escaped by the escape character esc. + */ +static int +isescaped(sp, p, esc) + const char *sp, *p; + int esc; +{ + const char *cp; + size_t ne; + +#if 0 + _DIAGASSERT(sp != NULL); + _DIAGASSERT(p != NULL); +#endif + + /* No escape character */ + if (esc == '\0') + return 1; + + /* Count the number of escape characters that precede ours */ + for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++) + continue; + + /* Return true if odd number of escape characters */ + return (ne & 1) != 0; +} + + +/* fparseln(): + * Read a line from a file parsing continuations ending in \ + * and eliminating trailing newlines, or comments starting with + * the comment char. + */ +char * +fparseln(fp, size, lineno, str, flags) + FILE *fp; + size_t *size; + size_t *lineno; + const char str[3]; + int flags; +{ + static const char dstr[3] = { '\\', '\\', '#' }; + + size_t s, len; + char *buf; + char *ptr, *cp; + int cnt; + char esc, con, nl, com; + +#if 0 + _DIAGASSERT(fp != NULL); +#endif + + len = 0; + buf = NULL; + cnt = 1; + + if (str == NULL) + str = dstr; + + esc = str[0]; + con = str[1]; + com = str[2]; + /* + * XXX: it would be cool to be able to specify the newline character, + * but unfortunately, fgetln does not let us + */ + nl = '\n'; + + while (cnt) { + cnt = 0; + + if (lineno) + (*lineno)++; + + if ((ptr = fgetln(fp, &s)) == NULL) + break; + + if (s && com) { /* Check and eliminate comments */ + for (cp = ptr; cp < ptr + s; cp++) + if (*cp == com && !isescaped(ptr, cp, esc)) { + s = cp - ptr; + cnt = s == 0 && buf == NULL; + break; + } + } + + if (s && nl) { /* Check and eliminate newlines */ + cp = &ptr[s - 1]; + + if (*cp == nl) + s--; /* forget newline */ + } + + if (s && con) { /* Check and eliminate continuations */ + cp = &ptr[s - 1]; + + if (*cp == con && !isescaped(ptr, cp, esc)) { + s--; /* forget escape */ + cnt = 1; + } + } + + if (s == 0 && buf != NULL) + continue; + + if ((cp = realloc(buf, len + s + 1)) == NULL) { + free(buf); + return NULL; + } + buf = cp; + + (void) memcpy(buf + len, ptr, s); + len += s; + buf[len] = '\0'; + } + + if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL && + strchr(buf, esc) != NULL) { + ptr = cp = buf; + while (cp[0] != '\0') { + int skipesc; + + while (cp[0] != '\0' && cp[0] != esc) + *ptr++ = *cp++; + if (cp[0] == '\0' || cp[1] == '\0') + break; + + skipesc = 0; + if (cp[1] == com) + skipesc += (flags & FPARSELN_UNESCCOMM); + if (cp[1] == con) + skipesc += (flags & FPARSELN_UNESCCONT); + if (cp[1] == esc) + skipesc += (flags & FPARSELN_UNESCESC); + if (cp[1] != com && cp[1] != con && cp[1] != esc) + skipesc = (flags & FPARSELN_UNESCREST); + + if (skipesc) + cp++; + else + *ptr++ = *cp++; + *ptr++ = *cp++; + } + *ptr = '\0'; + len = strlen(buf); + } + + if (size) + *size = len; + return buf; +} + +#ifdef TEST + +int main(int, char **); + +int +main(argc, argv) + int argc; + char **argv; +{ + char *ptr; + size_t size, line; + + line = 0; + while ((ptr = fparseln(stdin, &size, &line, NULL, + FPARSELN_UNESCALL)) != NULL) + printf("line %d (%d) |%s|\n", line, size, ptr); + return 0; +} + +/* + +# This is a test +line 1 +line 2 \ +line 3 # Comment +line 4 \# Not comment \\\\ + +# And a comment \ +line 5 \\\ +line 6 + +*/ + +#endif /* TEST */ diff --git a/util/opendev.3 b/util/opendev.3 new file mode 100644 index 0000000..81c5331 --- /dev/null +++ b/util/opendev.3 @@ -0,0 +1,104 @@ +.\" $OpenBSD: opendev.3,v 1.15 2002/05/01 08:03:30 mpech Exp $ +.\" +.\" Copyright (c) 2000, Todd C. Miller. All rights reserved. +.\" Copyright (c) 1996, Jason Downs. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must 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(S) ``AS IS'' AND ANY EXPRESS +.\" OR IMPLIED 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(S) BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (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 12, 2002 +.Dt OPENDEV 3 +.Os +.Sh NAME +.Nm opendev +.Nd short form device open routine +.Sh SYNOPSIS +.Fd #include +.Ft int +.Fn opendev "char *path" "int oflags" "int dflags" "char **realpath" +.Sh DESCRIPTION +The +.Fn opendev +function opens a device using the +.Dq short form +name. +This is typically +.Dq disk0s3 , +for instance, which will be expanded to +.Pa /dev/rdisk0s3 +on most architectures. +.Pp +Device name lookup is done by first checking +.Fa path +for a +.Dq / +and if one is found attempting to open that file. +Otherwise +.Fa /dev +is searched for a matching device. +.Pp +The +.Fa oflags +are the same as the +.Fa flags +passed to +.Xr open 2 . +.Pp +The +.Fa dflags +are specified by +.Tn OR Ns 'ing +the following values: +.Pp +.Bd -literal -offset indent -compact +OPENDEV_PART attempt to open the raw partition during expansion +OPENDEV_BLCK open the block device (default is character device) +.Ed +.Pp +The +.Dq raw +partition is defined as the partition which provides access to the entire +disk, regardless of the disk's partition map. +.Pp +If +.Fa realpath +is not +.Dv NULL , +it is modified to point at the fully expanded device name. +.Sh RETURN VALUES +The +.Fn opendev +return value and errors are the same as the return value and errors of +.Xr open 2 . +.Sh WARNINGS +If +.Fa realpath +is not +.Dv NULL , +on return it will point to internal +static storage space that will be overwritten by subsequent calls. +.Sh SEE ALSO +.Xr open 2 +.Sh HISTORY +The +.Fn opendev +function first appeared in +.Ox 1.2 . diff --git a/util/opendev.c b/util/opendev.c new file mode 100644 index 0000000..64ccb07 --- /dev/null +++ b/util/opendev.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 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 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, 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. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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(S) ``AS IS'' AND ANY EXPRESS + * OR IMPLIED 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(S) BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" + +int +opendev(path, oflags, dflags, realpath) + char *path; + int oflags; + int dflags; + char **realpath; +{ + int fd; + char *slash, *prefix; + static char namebuf[PATH_MAX]; + + /* Initial state */ + if (realpath) + *realpath = path; + fd = -1; + errno = ENOENT; + + if (dflags & OPENDEV_BLCK) + prefix = ""; /* block device */ + else + prefix = "r"; /* character device */ + + if ((slash = strchr(path, '/'))) + fd = open(path, oflags); + else if (dflags & OPENDEV_PART) { + if (snprintf(namebuf, sizeof(namebuf), "%s%s%s", + _PATH_DEV, prefix, path) < sizeof(namebuf)) { + char *slice; + while ((slice = strrchr(namebuf, 's')) && + isdigit(*(slice-1))) *slice = '\0'; + fd = open(namebuf, oflags); + if (realpath) + *realpath = namebuf; + } else + errno = ENAMETOOLONG; + } + if (!slash && fd == -1 && errno == ENOENT) { + if (snprintf(namebuf, sizeof(namebuf), "%s%s%s", + _PATH_DEV, prefix, path) < sizeof(namebuf)) { + fd = open(namebuf, oflags); + if (realpath) + *realpath = namebuf; + } else + errno = ENAMETOOLONG; + } + return (fd); +} diff --git a/util/pty.c b/util/pty.c index 22b990d..0491eea 100644 --- a/util/pty.c +++ b/util/pty.c @@ -68,6 +68,7 @@ #include #include #include +#include int openpty(amaster, aslave, name, termp, winp) int *amaster, *aslave; @@ -119,6 +120,7 @@ int openpty(amaster, aslave, name, termp, winp) return (-1); } +int forkpty(amaster, name, termp, winp) int *amaster; char *name; -- 2.45.2